When posting a blog, I want to create a category at the same time. Categories will use pre-created ones. Here’s the image of what I want to achieve. I’m using Rails 5.
Since blogs and categories are separate, I’ll use accepts_nested_attributes_for
to allow selecting a category while creating a blog.
#blog.rb
class Blog < ApplicationRecord
has_one :category, dependent: :destroy
accepts_nested_attributes_for :category, allow_destroy: true
end
Category:
class Category < ApplicationRecord
belongs_to :blog, optional: true
end
#BlogsController
def new
@blog = Blog.new
@blog.build_category
end
def blog_params
params.require(:blog).permit(
:title,
:content,
:editer,
category_attributes: [:id, :name]
)
end
Register the parent blog and the child category together. To apply Bootstrap classes to the select
element, use the following:
<%= category.select :name, ['Gadgets', 'Parenting', 'Entertainment', 'IT', 'Overseas', 'Lifestyle'], { include_blank: "Please select" }, class: "form-control" %>
_form.html.erb
<%= form_for(blog) do |f| %>
<div class="field">
<%= f.label :Category %>
<%= f.fields_for :category, @blog.category do |category| %>
<%= category.select :name, ['Gadgets', 'Parenting', 'Entertainment', 'IT', 'Overseas', 'Lifestyle'], { include_blank: "Please select" }, class: "form-control" %>
<% end %>
</div>
<div class="field">
<%= f.label :Title %>
<%= f.text_field :title, class: "form-control", placeholder: "Title" %>
</div>
<div class="actions">
<%= f.submit 'Create', class: "btn btn-primary btn-lg btn-block" %>
</div>
<% end %>
#schema.rb
enable_extension "plpgsql"
create_table "blogs", force: :cascade do |t|
t.string "title"
t.string "content"
t.string "editer"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "categories", force: :cascade do |t|
t.string "name"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "blog_id"
end
I tried creating it, and it worked successfully.
#blogs/show.html.erb
<p id="notice"><%= notice %></p>
<p>
<strong>Title:</strong>
<%= @blog.title %>
</p>
<p>
<strong>Content:</strong>
<%= @blog.content %>
</p>
<p>
<strong>Category:</strong>
<td><%= @blog.category.name %></td>
</p>
<p>
<strong>Editor:</strong>
<%= @blog.editer %>
</p>
<%= link_to 'Edit', edit_blog_path(@blog) %> |
<%= link_to 'Back', blogs_path %>
Initially, I thought about selecting categories from the database, but if the number of categories is small, this approach seems sufficient.