2010-12-14 36 views
1

Rails newb ici. Dans mon application, j'essaie de créer une base de données de jeux ayant chacun plusieurs MameControls comme attributs imbriqués. Les champs pour entrer dans MameControls apparaissent dans la vue New mais pas dans Edit, les résultats ne sont pas affichés dans Show, et si je valide valid_of: mameControls, il ne sauvegarde pas le formulaire, en indiquant "Les contrôles Mame ne peuvent pas être vides". Et dans la console rails, Game.first (ou last, ou tout autre enregistrement) .mame_controls renvoie uniquement []. Donc, autant que je sache, l'attribut imbriqué n'est pas sauvegardé, même si je suis à peu près sûr d'avoir tout mis en place de la même manière que ce qui est montré dans Railscast # 196. Voici la classe du jeu:Impossible d'enregistrer l'attribut imbriqué dans Rails

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_controls 

end 

mame_control.rb:

class MameControl < ActiveRecord::Base 
    belongs_to :game 

    attr_accessible :name, :game_action 
end 

Le code de formulaire pour entrer ou modifier MameControls est-ce.

dans _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> 

dans 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 

Répondre

1

D'accord, s'avère le problème était quelques choses mal avec mon utilisation de reject_if en accepts_nested_attributes_for. Tout d'abord, je vérifiais le mauvais nom de la variable (embarrassant) et j'ai mal compris ce que la méthode faisait réellement, ou plutôt ne pas faire - si une entrée précédemment remplie est rejetée pour être vide (comme dans ce lambda), elle gagne ' t supprime ou annule la valeur d'index correspondante dans le tableau. Ça ne fera rien. Vous devez définir explicitement l'enregistrement d'attribut imbriqué à _destroy pour le détruire. J'avais lu sur accepts_nested_attributes_for d'un point de vue théorique mais j'aurais dû mieux comprendre ses options.

0

Essayez d'ajouter :mame_controls_attributes-attr_accessible puis créer l'enregistrement. Ensuite, lorsque vous modifiez l'enregistrement, la vue d'édition doit également afficher les champs mame_controls.

De même, pourquoi les contrôles devraient-ils être visibles dans l'action show? (montrer est destiné à afficher les données, pas l'éditer)

+0

Merci, mais j'ai peur d'ajouter: mame_controls_attributes à attr_accessible ne fait aucune différence. Et ne vous inquiétez pas, les contrôles ne sont pas dans l'action show. Ce que je voulais dire, c'est simplement que les données ne sont pas affichées (en tant qu'informations statiques). Désolé de ne pas être clair à ce sujet, j'ai corrigé le post original. – user541269

0

Je rencontrais un problème similaire. J'ai obtenu le formulaire imbriqué à afficher correctement, mais lorsque j'ai soumis le formulaire il a écrit l'information d'objet parent à la base de données, mais pas l'objet enfant (imbriqué).

La solution pour moi ajoutais le code suivant à mon (comme si j'utilisais votre exemple) créer méthode games_controller.rb

def create 
    @game = Game.new(params[:game]) 
    if @game.save 
    @game.mame_control = MameControl.new(params[:mame_control]) 
    ... 

Et s'il vous plaît noter aussi que mon objet parent avait une relation has_one avec l'enfant, pas has_many.