投稿に紐づいた情報を出す方法
主に2つのパターンがある。
1つは、モデル内の情報を出す場合。
これはユーザーモデルのnicknameカラムや、ageカラムの情報を表示することが該当する。
2つ目は、モデルに紐づいた情報を表示する場合。
ある投稿に対して、投稿者の名前を表示するなどの場合が該当する。
投稿アプリの構造
例えば、以下のような構造になっているとする。
#Userテーブルの構成 t.string :nickname, null: false, default:"" t.string :email, null: false, default:"" t.string :encrypted_password, null: false, default: ""
#Userモデルのアソシエーション has_many :posts
#Postテーブルの構成 t.text :content, null: false t.references :user, null: false, foreign_key: true
#Postテーブルのアソシエーション belongs_to :users
1.モデルの情報を表示する方法
Postモデルのcontentsカラムの情報を表示する場合は以下のように記述すれば良い。
#postsコントローラーの記述 def index @post = Post.find(params[:id]) end
#posts/index.html.erbの記述 <%= @post.content %>
この際、以下の点に注意する必要がある。
- コントローラーとビューの変数は一致しているか?(@post)
- コントローラーとビューのアクションは一致しているか?(indexアクションとindex.html.erb)
- カラム名は間違っていないか?(content)
2.紐づいた情報を表示する方法
例えば、投稿者の名前を表示したい場合。
Postsテーブルには投稿者の名前のカラムが存在しないため、アソシエーションを活用する必要がある。
#postsコントローラーの記述 def index @post = Post.find(params[:id]) end
#posts/index.html.erbの記述 <%= @post.user.nickname %>
@post.user.nicknameについて、以下のように分解できる。
- @postはコントローラーで定義した、ある一つの投稿(post)である。
- userは、Usersテーブルのことである。
- nicknameは、Usersテーブルのカラムである。
別の言い方をすれば、以下のようにも考えられる。
@post.user + user.nickname = @post.user.nickname
つまり、「Postモデルに紐づいているUserモデルの情報を取り出す記述」と「Userモデルに存在するカラムを取り出す記述」を足し合わせた記法なのである。
注意すべき点は以下の通り。
- アソシエーションが間違いなく組まれているか? (アソシエーションが記述されていない場合、モデル間の関連が成り立たないため、このような記述はできない。undefined method errorなどが発生する。 )
- コントローラーに適したインスタンス変数を定義したか?(Userの情報を取り出したいからと言って、「@user = User.find(params[:id])」を定義するのはナンセンスである。あくまでスタート地点は投稿(post)なのであるから、postコントローラーに@postを定義するべきである。)