LoginSignup
17
20

More than 5 years have passed since last update.

Ruby on Rails ~お気に入り登録(ブックマーク)機能の実装2 - ブックマークしたユーザー数と一覧の表示(コードメモ)

Posted at

今回は、以前実装したお気に入り登録(ブックマーク)に、いくつか機能を付け加えていきます。

前回:Ruby on Rails ~お気に入り登録(ブックマーク)機能の実装 http://qiita.com/wtb114/items/39367a39bd6a65701db7

実装するもの
1.ブックマークしたユーザー数の取得
2.ブックマークしたユーザーの一覧を取得
3.同じユーザーによるブックマークの重複登録を防ぐ
※「いいね!」などを実装する場合も、コピペで使用できます。

1.修正前の確認

◆イベント一覧から興味のあるイベントをブックマークする機能です。
イベントは"Event"、ブックマークに使うモデルは"Clip"を使っています。

・ルート

config/routes.rb
  resources :events do
    member do
      post "add", to: "clips#create"
    end
  end

  resources :clips, only: [:destroy]

・モデル

app/models/clip.rb
class Clip < ActiveRecord::Base
    belongs_to :user
    belongs_to :event
end
app/models/event.rb
class Event < ActiveRecord::Base
    has_many :clips
    has_many :users, through: :clips
end
app/models/user.rb
class User < ActiveRecord::Base
    has_many :clips
    has_many :events, through: :clips
end

・コントローラー

app/controllers/clips_controller.rb
class ClipsController < ApplicationController
  def create


    @user_id = current_user.id
    @event_id = Event.find(params[:id]).id
    @clip = Clip.new(event_id: @event_id, user_id: @user_id)


      if @event.save
        redirect_to user_path(current_user)
      end

  end

  def destroy
    @clip = Clip.find(params[:id])
    if @clip.destroy
      redirect_to user_path(current_user)
    end
  end

end

・ビュー

app/views/events/show.html.erb
      <div>
      <%= link_to "このイベントをクリップ", add_event_path(event), method: :post %>
      </div>

2.ルートの編集

config/routes.rb

resources :events do
    member do
      post "add", to: "clips#create"
      get "show_clips" => "clips#show_clips"
    end
  end
  resources :clips, only: [:destroy, :index]

後ほど、"show_clip"で、あるイベントをブックマークしたユーザーを表示させるビューを作ります。
get "show_clips" => "clips#show_clips" を :eventsにネストし記述することで、clipにeventのidを紐付けます。

$ rake routes
=> 
show_clips_event GET      /events/:id/show_clips(.:format)         clips#show_clips

このようなルートができていると思います。

3.モデルの編集

app/models/clip.rb
class Clip < ActiveRecord::Base

    validates :user_id, :uniqueness => {:scope => :event_id}

    belongs_to :user
    belongs_to :event
end

Clipモデルに"validates :user_id, :uniqueness => {:scope => :event_id}"を記述します。
こうすることで、同じユーザーが同じイベントをブックマークできないようになります。(すでに保存されているClipのevent_idの場合に、user_idがユニークであるかどうか。)
"いいね!"機能など、重複して保存されないような機能を実装する場合にも使えます。

app/models/event.rb
class Event < ActiveRecord::Base
    has_many :clips
    has_many :users, through: :clips
end
app/models/user.rb
class User < ActiveRecord::Base
    has_many :clips
    has_many :events, through: :clips
end

4.コントローラーの編集

app/controllers/clips_controller.rb
class ClipsController < ApplicationController
  def create

    @user_id = current_user.id
    @event_id = Event.find(params[:id]).id
    @clip = Clip.new(event_id: @event_id, user_id: @user_id)

#以下、追記############################################################
    if @clip.save
      redirect_to clips_path(current_user)
    else
      redirect_to clips_path(current_user)
    end
###############varidateの結果、ブックマークに成功した場合と失敗した場合の処理を記述

  end

  def destroy
    @clip = Clip.find(params[:id])
    if @clip.destroy
      redirect_to user_path(current_user)
    end
  end
end

さらに2つのビューをつくるため。下記を追記。
"index"はユーザーがブックマークしたイベントを一覧で取得するページ。
"show_clips"は、あるイベントにブックマークしたユーザー一覧を取得するページ。

app/controllers/clips_controller.rb
  def index
    @user = current_user
    @clips = Clip.where(user_id: @user.id).all
  end

  def show_clips
    @event = Event.find(params[:id])
    @clips = Clip.where(event_id: @event.id).all
  end

5.ビューの編集

2つのビューを追加。

・ユーザーがブックマークしたイベントを一覧で取得するページ。

app/views/clips/index.html.erb
  <h2>参加中のイベント</h2>
    <% @clips.each do |clip| %>
      <% event = Event.find(clip.event_id) %>
            <div class="name3"><%= link_to event.event_name, event_path(event) %></div>
            <div class="name2"><%= link_to "参加中のイベントから削除",clip_path(clip), method: :delete %></div>
            <div class="name2">
            <%= event.event_date.strftime("%Y-%m-%d %H:%M:%S")  %>
            </div>
            <div class="name2">
            <%= event.event_location %>
            </div>
    <br />
    <% end %>
</div>

・あるイベントにブックマークしたユーザー一覧を取得するページ。

app/views/clips/show_clips.html.erb

  <h2>ユーザー一覧(<%= @clips.length %>人)</h2>

    <% @clips.each do |clip| %>
      <% @user_id = clip.user_id %>
      <% user = User.find(@user_id) %>
      <div class ="name2">
        <%= link_to user.username ,user_path(user) %><br/>
      </div>
    <% end %>

以上で実装が完了しました。

17
20
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
17
20