UserとPhotoの関連付け
ユーザーと写真の関連付けを行います。すでに存在するモデルに対して変更を行い、関連付けができるようにしていきます。
カラム追加
photosテーブルにuser_idというカラムを追加します。
rails g migration add_column_to_photos user_id
DBに変更を反映させます。
rake db:migrate
UserとPhotoの関連付け
UserとPhotoの関連付けを行います。
app/models/user.rbをエディタで開きます。この行のあとに
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable, :omniauthable
この行を追加します。
has_many :photos
app/models/photo.rbをエディタで開きます。この行のあとに
mount_uploader :image, ImageUploader
この行を追加します。
belongs_to :user
app/controllers/photos_controller.rbをエディタで開きます。この行を
def new
@photo = Photo.new
end
このように変更します。
def new
@photo = current_user.photos.build
end
この行を
def photo_params
params.require(:photo).permit(:image, :caption)
end
このように変更します。
def photo_params
params.require(:photo).permit(:image, :caption, :user_id)
end
Photoはidから検索していました。ユーザーに関連付くデータを取得するようにします。このコードを
def set_photo
@photo = Photo.find(params[:id])
end
このように変更します。
def set_current_user_photo
@photo = current_user.photos.find(params[:id])
end
この行を
before_action :set_photo, only: [:show, :edit, :update, :destroy]
このように変更します。
before_action :set_current_user_photo, only: [:edit, :update, :destroy]
showではユーザーに紐付かないデータを表示しても問題ないため、このコードを
def show
end
このように変更します。
def show
@photo = Photo.find(params[:id])
end
app/views/photos/_form.html.erbをエディタで開きます。この行のあとに
<div class="field">
<%= f.label :caption %><br>
<%= f.text_area :caption %>
</div>
この行を追加します。
<%= f.hidden_field :user_id %>
サーバーを起動し、ログインできるか確認します。すでにサーバーが起動している場合は、再起動してください。
rails s
ログイン後に新しい写真を登録し、関連付けられているか確認します。サーバーを起動したターミナルとは別のターミナルで、Railsコンソールを起動します。
rails c
最後の写真のユーザーを確認します。
Photo.last.user
このようにユーザーの情報が表示されていれば、UserとPhotoの関連付けができています。
[1] pry(main)> Photo.last.user
Photo Load (0.2ms) SELECT "photos".* FROM "photos" ORDER BY "photos"."id" DESC LIMIT 1
User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1 [["id", 1]]
#<User:0x007f8821a5e460> {
:id => 1,
:email => "0000000-twitter@example.com",
:encrypted_password => "xxxx",
:reset_password_token => nil,
:reset_password_sent_at => nil,
:remember_created_at => nil,
:sign_in_count => 5,
:current_sign_in_at => Tue, 05 Jan 2016 22:34:41 UTC +00:00,
:last_sign_in_at => Tue, 05 Jan 2016 00:28:43 UTC +00:00,
:current_sign_in_ip => "::1",
:last_sign_in_ip => "::1",
:created_at => Sat, 19 Dec 2015 04:38:22 UTC +00:00,
:updated_at => Tue, 05 Jan 2016 22:34:41 UTC +00:00,
:provider => "twitter",
:uid => "0000000",
:user_name => "xxxxx",
:avatar_url => "http://pbs.twimg.com/profile_images/xxx.jpg"
}
この状態では、ログインせずに写真を登録しようとするとエラーが発生します。次はログインチェックを実装します。
これまでに作成したデータは、UserとPhotoが関連付けられていないため削除します。Railsコンソールで以下のコードを実行すると、すべてのPhotoが削除できます。
Photo.all.each(&:destroy)