Labyrinth of Wisdom

-This is My Archive-


お気に入り機能サンプル②(完結)

引き続き、Railsでお気に入り機能のサンプルを作成していきます。

前回は各ユーザが持っているお気に入り一覧を表示させるところまで作成しました。

今回はログインしたユーザがお気に入りの本を登録・削除する、という仕上げの部分を行っていきます。

コントローラ

まずコマンドラインからfavoritesコントローラーを作成します。

rails g controller favorites

次にお気に入りを登録するcreate、お気に入りを削除するdestroyアクションを記述します。

セッションに格納したログインユーザのIDと、本一覧画面から選んだ特定の本のIDを初期値として新しいレコードを作ることで、ユーザ別のお気に入りを登録できる様になります。

お気に入りの削除は、ユーザ別のお気に入り一覧(ユーザ詳細画面内)から特定のお気に入りを選びdestroyメソッドを使うことで可能になります。

  • app/controllers/favorites_controller.rb
  #お気に入り登録用アクション
  def create
    @user_id = session[:id] #ログインしたユーザのID
    @book_id = Book.find(params[:id]).id #特定の本のID
    #book_idに@book_id、user_idに@user_idを入れて、Favoriteモデルに新しいオブジェクトを作る
    @favorite = Favorite.new(book_id: @book_id, user_id: @user_id)
    if @favorite.save
      #保存に成功した場合、本一覧画面に戻る
      redirect_to books_path
    end
  end

  #お気に入り削除用アクション
  def destroy
    @favorite = Favorite.find(params[:id])
    if @favorite.destroy
      #削除に成功した場合、ログインしているユーザの詳細画面に戻る
      redirect_to user_path(session[:id])
  end

ルーティング

先ほど作成したfavoritesコントローラと各アクションにルーティングをしていきます。

お気に入りを登録するcreateアクションは、本一覧から特定の本を選んで登録するので、resources booksの入れ子でルーティングをしています。その際アクション名をaddに指定しています。

お気に入りを削除するdestroyアクションは複数リソースのonlyオプションでルーティングしています。

  • config/routes.rb
  root "top#index"
  resource :sessions, only: [:new, :create, :destroy]
  resources :users

  #以下今回追加分
  resources :books do
    member do #本一覧画面からお気に入り登録をする
      post "add", to: "favorites#create"
    end
  end
  #個人ページからお気に入りを削除する
  resources :favorites, only: [:destroy]

f:id:Labyrinth_of_Wisdom:20160304092540p:plain

ビュー

本一覧画面にお気に入り登録のリンクを記述します。

  • app/views/books/index.html.erb
<table>
  <thead>
    <tr>
      <th></th><th>タイトル</th><th>価格</th>
    </tr>
  </thead>
  <tbody>
    <% @books.each do |book| %>
      <tr>
        <!-- お気に入り登録ボタン ルートに従いパスを記述、POSTメソッドに指定 -->
        <td><%= link_to "登録", add_book_path(book), method: :post %></td>
        <!-- 本の詳細へのリンク -->
        <td><%= link_to book.name,book_path(book) %></td>
        <td><%= book.price %></td>
      </tr>
    <% end %>
  </tbody>
</table>

ユーザの詳細画面を修正していきます。 削除リンクのパスfavorite_pathの引数を@favorite[i][:id]にすることで、お気に入りレコードのIDが取得できるので、これでレコードを削除するパスが生成されます。(実は@favorite[i]でもいけます)

  • app/views/users/show.html.erb
<h3>お気に入りの本</h3>
<table>
  <thead>
    <tr>
      <th>削除</th>
      <th>タイトル</th>
      <th>価格</th>
    </tr>
  </thead>
  <tbody>
    <!-- 削除リンクの為にindex付きのメソッドを使用 -->
    <% @user.books.each_with_index do |book, i| %>
      <tr>
        <td><%= link_to "削除",favorite_path(@favorites[i][:id]), method: :delete %></td>
        <td><%= book.name %></td>
        <td><%= book.price %></td>
      </tr>
    <% end %>
  </tbody>
</table>

これでひとまずログインしたユーザが本をお気に入りを登録・削除できる機能が実装できました。

以上。

参考 ルーティングを極める (後編) | TechRacho