2009-12-22 4 views
2

J'ai un objet modèle Post qui fait référence à un objet parent. Les méthodes edit, new et reply utilisent toutes le même modèle partiel.Rails: Comment envoyer un objet avec un formulaire?

Les posts_controller méthodes:

def edit 
    @post = Post.find(params[:id]) 
end 

def reply 
    @post = Post.new 
    @replypost = Post.find(params[:id]) 
    @post.title = @replypost.title 
    @post.parent = @replypost 
end 

Le code de modèle partiel:

<% form_for(@post) do |f| %> 
    <%= f.error_messages %> 

    <p> 
    <%= f.label :title %><br /> 
    <%= f.text_field :title %> 
    </p> 
    <p> 
    <%= f.label :body %><br /> 
    <%= f.text_area :body %> 
    </p> 
    <%= if :parent then f.hidden_field :parent end %> 
    <p> 
    <%= f.submit "Create" %> 
    </p> 
<% end %> 

Si je regarde le code source HTML généré par le modèle partiel, je peux voir que je passe une sorte de l'objet id à ma méthode create.

<input id="post_parent" name="post[parent]" type="hidden" value="#&lt;Post:0x103e3bdf0&gt;" /> 

Le problème est que quand je tente de sauver ce nouvel objet, je l'ai créé, je reçois un avertissement qu'il attendait un poste et obtenu une chaîne. Je suis sûr que je peux contourner ce problème en définissant et en obtenant le parent_id et en le passant avec mon formulaire, mais je me demande s'il n'y a pas une meilleure façon de le faire, quelque chose de plus élégant et Rails-esque.

Répondre

5

essayer <%= f.hidden_field :parent_id unless @post.parent.nil? %>

Cela va passer l'ID parent avec le poste et vous pouvez alors .find(params[:post][:parent_id]) si vous avez besoin de l'objet plus tard.

+0

parfait. Merci! – kubi

+0

En gardant à l'esprit que l'utilisation de l'option UNLESS (ou IF dans votre question) aura pour résultat que le champ caché n'est pas créé du tout, donc params [: post] [: parent_id] pourrait être null –

1

De quoi il ressemble,

<%= if :parent then f.hidden_field :parent end %> 

n'est pas en mesure de déduire que lorsque vous dites: parent, vous voulez que la valeur du champ caché pour être l'ID du poste parent.

Vous devez utiliser explicitement l'attribut: parent_id pour générer la valeur du champ masqué car il ne peut pas être déduit comme il peut le faire ailleurs dans Rails.

2

Pour les personnes qui cherchent à envoyer un objet au lieu d'un identifiant (utile lorsque vous avez un objet non enregistré), vous pouvez effectuer les opérations suivantes:

À votre avis:

<% form_for(@post) do |f| %> 
    ... 
    <%= hidden_field_tag :param_name, @object.to_param %> 

Dans votre contrôleur:

object = Rack::Utils.parse_nested_query params[:param_name] 

Fonctionne pour les hachages imbriqués. N'ont pas testé avec des tableaux ou des hachages de tableaux.

J'ai trouvé cela nécessaire lors de la construction d'un objet sur plusieurs vues qui ne passeraient pas la validation si j'ai essayé de sauvegarder plus tôt.

Avertissement: Les données de @object sont visibles par l'utilisateur dans hidden_field_tag. Ils ont juste besoin de cliquer sur "Voir la source". Réfléchissez attentivement aux objets que vous souhaitez sérialiser avec cette méthode.

Questions connexes