Reputation: 2847
Why am I getting this error?:
TypeError (no implicit conversion of Symbol into Integer)
in the create action in the posts_controller:
posts_controller.rb
@post = @character.posts.create(post_params)
...
def post_params
params.require(:post).permit( conversation_attributes: [ missives_attributes: [ :content ] ] )
end
post.rb
has_one :conversation, class_name: 'Postconversation', dependent: :destroy
accepts_nested_attributes_for :conversation
postconversation.rb
has_many :missives, class_name: 'Postmissive', dependent: :destroy
accepts_nested_attributes_for :missives
_post_form.html.erb
<%= f.fields_for :conversation_attributes do |ff| %>
<%= ff.fields_for :missives_attributes do |fff| %>
<%= hidden_field_tag :callsign, character.callsign %>
<%= fff.text_area :content %>
...
<% end %>
<% end %>
Logs
Parameters: {"utf8"=>"✓", "authenticity_token"=>"mxHD...VoA==", "callsign"=>"baz", "post"=>{"conversation_attributes"=>{"missives_attributes"=>{"content"=>"Hello"}}}}
EDIT
According to this question, it looks like I need square brackets around my submitted parameters: Strong parameters with has_many gives "no implicit conversion of Symbol into Integer"
Parameters: {"utf8"=>"✓", "authenticity_token"=>"mxHD...VoA==", "callsign"=>"baz", "post"=>{"conversation_attributes"=> [ {"missives_attributes"=> [ {"content"=>"Hello"} ] } ] }}
But how do I achieve this in the post form??
Upvotes: 0
Views: 874
Reputation: 2847
I finally got it working:
posts_controller.rb
@post = @character.posts.create(post_params)
...
def post_params
params.require(:post).permit( conversation_attributes: [ missives_attributes: [ :content ] ] )
end
post.rb
has_one :conversation, class_name: 'Postconversation', dependent: :destroy, inverse_of: :post
accepts_nested_attributes_for :conversation
postconversation.rb
belongs_to :post, inverse_of: :conversation
has_many :missives, class_name: 'Postmissive', dependent: :destroy, foreign_key: 'conversation_id', inverse_of: :conversation
accepts_nested_attributes_for :missives
postmissive.rb
belongs_to :conversation, class_name: 'Postconversation', foreign_key: 'conversation_id', inverse_of: :missives
validates :conversation, presence: true # validates :conversation_id does not work
_post_form.html.erb
<%= f.fields_for :conversation_attributes do |ff| %>
<%= ff.fields_for 'missives_attributes[]', Postmissive.new do |fff| %>
<%= hidden_field_tag :callsign, character.callsign %>
<%= fff.text_area :content %>
...
<% end %>
<% end %>
Submitted Parameters
Parameters: {"utf8"=>"✓", "authenticity_token"=>"mxHD...VoA==", "callsign"=>"baz", "post"=>{"conversation_attributes"=>{"missives_attributes"=>[{"content"=>"Hello"}]}}}
Notes
1) Note the addition of inverse_of:
so Rails recognises the bi-directional association. The database save fails without this. The docs say it's only necessary to use with has_one
and has_many
, but some Stack Overflow answers say it should also be used with the belongs_to
, so that's what I've done (belongs_to :post, inverse_of: :conversation
and belongs_to :conversation, inverse_of: :missives
). Further insight on this welcome.
2) post_params
are fine as is. No need for the addition of any brackets.
3) In postmissive.rb
, the validation had to be validates :conversation
, not validates :conversation_id
.
4) Stephan Wiehr was right, the missives_attributes
had to be submitted as an array. Thanks to Kartikey Tanna for this answer on how to achieve this.
Upvotes: 1
Reputation: 18647
Since, missives_attributes
contain content
You shld use, <%= fff.text_area :content %>
for missives_attributes
and not <%= f.text_area :content %>
<%= f.fields_for :conversation_attributes do |ff| %>
<%= ff.fields_for :missives_attributes do |fff| %>
<%= hidden_field_tag :callsign, character.callsign %>
<%= fff.text_area :content %>
...
<% end %>
<% end %>
Upvotes: 1