Ruby on Railsを触ってみる ⑧モデルのリレーションシップ
前回の時点で作成したモデルはTweet、Userの2つ。Userはユーザー認証のために作成したが、TweetはUserに紐付いていないため、どのユーザーが登録したツイートかがわからない。そこで、この2つを関連付けたい。
まずはTweetにuser_idを追加する。
$ rails g migration add_user_id_to_tweets user_id:integer
作成されたmigrationファイル。
class AddUserIdToTweets < ActiveRecord::Migration def change add_column :tweets, :user_id, :integer end end
rakeコマンドを実行して、テーブルに列を追加する。
$ rake db:migrate
各modelにリレーションシップの記述を追記する。 Tweetは1つのUserに紐付いているためbelongs_toとなる。
class Tweet < ActiveRecord::Base belongs_to :user
Userは複数のTweetをもつためhas_manyとなる。
class User < ActiveRecord::Base devise :trackable, :omniauthable has_many :tweet, dependent: :destroy
controllerを修正する。 tweet_controller.rbのindexを修正し、ログイン済みユーザに属するツイートのみの表示とする。また、import_csvの中で、モデルのimport_csvを呼び出す引数に、ログイン中のユーザを追加しておく。
def index - @tweets = Tweet.order(:id).page params[:page] + @user = current_user + @tweets = @user.tweet.order(:id).page params[:page] end # GET /tweets/1 @@ -71,7 +72,7 @@ class TweetsController < ApplicationController # POST /tweets/import_csv def import_csv respond_to do |format| - if Tweet.import_csv(params[:csv_file]) + if Tweet.import_csv(params[:csv_file],current_user) format.html { redirect_to tweets_path } format.json { head :no_content }
また、modelに記述されているツイートの登録も修正する。 引数にUserモデルを追加する。列user_idにはuserのidをセットする。 また、取り込み前の削除では、userに関連したレコードのみを削除したいので、修正しておく。 差分はこんな感じになる。
class Tweet < ActiveRecord::Base - def self.import_csv(csv_file) + belongs_to :user + + def self.import_csv(csv_file,user) # csvファイルを受け取って文字列にする csv_text = csv_file.read @@ -28,7 +30,8 @@ class Tweet < ActiveRecord::Base tweet.retweeted_status_user_id = row[7] tweet.retweeted_status_timestamp = row[8] tweet.expanded_urls = row[9] - + tweet.user_id = user.id + tweet.save end
まず、現在登録されているツイートはどのユーザにも属していないので、通常どおりアクセスすると、表示されない。
ユーザを変えて取り込みなおすと、ログインしたユーザとして取り込んだツイートが表示される。
Add relationships between Users and Tweets twata701/twice GitHub