Can't save nested attribute in Rails
Rails newb here. In my app I'm trying to create a database of Games that each have multiple MameControls as nested attributes. The fields for entering MameControls show up in the New view but not in Edit, the results aren't rendered in Show, and if i validate_presence_of :mameControls it won't save the form, stating "Mame controls can't be blank." And in the rails console, Game.first(or last, or any other record).mame_controls returns only []
. So as far as I can tell the nested attribute is not being saved, even though i'm pretty sure i've set everything up similarly to what is shown in Railscast #196. Here is the Game class:
class Game < ActiveRecord::Base
has_many :mame_controls, :dependent => :destroy
attr_accessible :name, :year, :company, :designer, :genre,
:sb_info, :wiki_link, :arcade_history_link, :arcade_museum_link,
:caesar_link, :wildcard_link, :mame_controls
accepts_nested_attributes_for :mame_controls, :reject_if => lambda { |a| a[:content].blank? }, :allow_destroy => true
validates_presence_of :name, :year, :company, :genre, :sb_info, :mame_control开发者_Python百科s
end
mame_control.rb:
class MameControl < ActiveRecord::Base
belongs_to :game
attr_accessible :name, :game_action
end
The form code to enter in or edit MameControls is this.
in _form.html.erb:
<% f.fields_for :mame_controls do |builder| %>
<%= render "control_fields", :f => builder %>
<% end %>
_control_fields.html.erb:
<div class="field">
<p>
<%= f.label :name, "Mame Control Name" %><br />
<%= f.text_field :name %><br />
<%= f.label :game_action, "Game Action" %><br />
<%= f.text_field :game_action %>
</p>
</div>
in games_controller.rb:
def new
@game = Game.new
5.times do
mame_control = @game.mame_controls.build
end
end
def create
@game = Game.new(params[:game])
end
Alright, turns out the problem was a couple things wrong with my use of reject_if
in accepts_nested_attributes_for
. First of all I was checking for the wrong variable name (embarrassing,) and I misunderstood what the method was actually doing, or rather not doing - if a previously filled entry is rejected for being blank (as in that lambda), it won't delete or null the corresponding index value in the array. It just won't do anything to it. You have to explicitly set the nested attribute record to _destroy
to destroy. I had read up on accepts_nested_attributes_for
from a theoretical standpoint but I should've understood its options better.
Try adding :mame_controls_attributes
to attr_accessible
and then creating the record. Then, when you edit the record, the edit view should also show the fields for mame_controls
.
Also, why should the controls be visible in show action ? (show is meant to display the data, not edit it)
I was experiencing a similar problem. I got the nested form to display correctly, but when I submitted the form it wrote the parent object info to the database, but not the child (nested) object.
The solution for me was adding the following code to my (as if I were using your example) create method in games_controller.rb
def create
@game = Game.new(params[:game])
if @game.save
@game.mame_control = MameControl.new(params[:mame_control])
...
And please also note that my parent object had a has_one relationship with the child, not has_many.
精彩评论