Rails 4 has_one association form not building
Solution 1
Question #1: Yes, you need to add the :category_attributes
in the post_params
strong parameter method like this:
def post_params
params.require(:post).permit(:body, category_attributes: [:title])
end
Question #2: Yes, the parameters should be nested, this is a typo in your view because you are not applying the fields_for
(plural by the way) in the scope of the parent form builder, also you are not using the category_fields
form builder inside the fields_for
block!
The view should look like this:
<%= form_for @post do |form| %>
<%= form.label :body %>
<%= form.text_area :body %>
<%= form.fields_for :category do |category_fields| %>
<%= category_fields.label :title %>
<%= category_fields.text_field :title %>
<% end %>
<%= form.button "Add Post" %>
<% end %>
Question #3: The button parameter might be in the wrong place due to the mixed up form building in your view.
Question #4: You don't need to build the child model in your create action if you accept nested attributes
Question #5: Yes, the validation of the child model is also run and if the validation of the child fails, the parent will also have an error and is not saved to the database.
Solution 2
@sled you are right. But for future Rails 4.1 bolded (**) will be deprecated
def post_params
params.require(:post).permit **(:body, :category_attributes => [:title])**
end
bolded will be forced to be so (:body, category_attributes: [:title])
Related videos on Youtube
Wasabi Developer
Updated on June 04, 2022Comments
-
Wasabi Developer almost 2 years
I need some pointers on how Rails 4 works with has_one and belongs_to association.
My form doesn't save the
has_one
relationshipPost Model
class Post < ActiveRecord::Base validates: :body, presence: true has_one :category, dependent: :destroy accepts_nested_attributes_for :category end class Category < ActiveRecord::Base validates :title, presence: true belongs_to :post end
Post Controller
class PostController < ApplicationController def new @post = Post.new @post.build_category end def create @post = Post.new(post_params) end private def post_params params.require(:post).permit(:body) end end
Form in the Post#new action
<%= form_for @post do |form| %> <%= form.label :body %> <%= form.text_area :body %> <%= fields_for :category do |category_fields| %> <%= category_fields.label :title %> <%= category_fields.text_field :title %> <% end %> <%= form.button "Add Post" %> <% end %>
It's not saving the
category
title when the Post form is submitted.Debug params
utf8: ✓ authenticity_token: 08/I6MsYjNUhzg4W+9SWuvXbSdN7WX2x6l2TmNwRl40= post: !ruby/hash:ActionController::Parameters body: 'The best ice cream sandwich ever' category: !ruby/hash:ActiveSupport::HashWithIndifferentAccess title: 'Cold Treats' button: '' action: create controller: posts
App log
Processing by BusinessesController#create as HTML Parameters: {"utf8"=>"✓", "authenticity_token"=>"08/I6MsYjNUhzg4W+9SWuvXbSdN7WX2x6l2TmNwRl40=", "post"=>{"body"=>"The best ice cream sandwich ever"}, "category"=>{"title"=>"Cold Treats", "button"=>""}
In the Rails console.. I can run the following succesfully
> a = Post.new => #<Post id: nil, body: ""> > a.category => nil > b = Post.new => #<Post id: nil, body: ""> > b.build_category => #<Post id: nil, title: nil> > b.body = "The best ice cream sandwich ever" => "The best ice cream sandwich ever" > b.category.title = "Cold Treats" => "Cold Treats"
The questions I have the relates to how to tackle this problem:
- I'm not sure if I have to add
:category_attributes
in thepost_params
strong parameter method? - Should the logs and debug params show that the
Category
attributes are nested inside thePost
parameter? - In the
Category
hash parameter there is a blankbutton
key that isn't in myfields_for
am I missing something when using the form helpers? - Is the reason because the create action doesn't take the
build_category
method and I will need to add this to the create action? - Will validations on the
Category
model (presence: true
) be automatically used on thePost
form?
Thanks in advance.
Update: missing
category_fields
insidefields_for
block. - I'm not sure if I have to add
-
Wasabi Developer over 10 yearsSled, you sir are a gentleman. Thank you for pointing out my wrong ways. I have been looking at the same form for days not know that I needed to add form.builder inside the fields_for block. Thanks again for clarifying the strong parameter nested attributes. I really appreciate the time you took to answer all my questions. Thank you! :)