Edited at

Rails4で実戦的なブログを作成(その3)

More than 5 years have passed since last update.


カテゴリを作成する

次に記事が属するカテゴリを作成します。カテゴリは名前(name)のみを持ちます。

$ rails g scaffold Category name:string

$ rake db:migrate


名前の入力を必須にする

見出しまたは本文が未設定の状態でポストできることは望ましくないため、必須項目に設定します。項目が空でないことを検証すればよいので、validates_presence_of宣言を使います。


app/models/post.rb

class Post < ActiveRecord::Base

validates_presence_of :title
validates_presence_of :body
end


記事にカテゴリへのリレーションを追加する

話を簡単にするために記事は1つのカテゴリのみを持つようにします。記事(posts)にカテゴリID(category_id)を追加するため、マイグレーションスクリプトを生成します。

$ rails g migration AddCategoryIdToPosts

生成したマイグレーションスクリプトを次のように編集します。


db/migrate/YYYYMMDDHHMMDD_add_category_id_to_posts.rb

class AddCategoryIdToPosts < ActiveRecord::Migration

def self.up
add_column(:posts, :category_id, :integer)
add_index(:posts, :category_id)
end

def self.down
remove_index(:posts, :column => :category_id)
remove_column(:posts, :category_id)
end
end


記事からカテゴリへのリレーションはn対1の関係なので、belongs_to宣言を書きます。この時、指定する1側は単数形で書きます。


app/models/post.rb

class Post < ActiveRecord::Base

validates_presence_of :title
validates_presence_of :body
belongs_to :blog
belongs_to :category
end

一方、カテゴリから記事へは1対nの関係なので、has_many宣言を書きます。この時、指定するn側は複数形で書きます。


app/models/category.rb

class Category < ActiveRecord::Base

has_many :posts
end

マイグレーションを実行します。

$ rake db:migrate


記事投稿時にカテゴリを指定できるようにする

_form.html.erbに以下を追加して、カテゴリを指定できるようにします。


app/views/posts/_form.html.erb

<div class="field">

<%= f.label :category_id %><br />
<%= f.collection_select :category_id, Category.all, :id, :name %>
</div>

ただ、このままではcategory_idは許可されていないパラメータとして弾かれてしまうため、posts_controller.rbのpost_paramsメソッドを次のように書き換えます。


app/controllers/post_controller.rb

def post_params

params.require(:post).permit(:title, :body, :category_id)
end

これで、カテゴリを指定できるようになり、それがDBにも反映されるようになります。


カテゴリを追加し、記事で選択できることを確認する

サーバを起動し、適当にカテゴリを追加した後、記事投稿時に選択できることを確認します。