2010-02-06 9 views
25

Tengo dos modelos, enlaces y etiquetas, asociados a través de un tercero, link_tags. El siguiente código está en mi modelo de enlace.accept_nested_attributes_for con has_many =>: a través de Opciones

Asociaciones:

class Link < ActiveRecord::Base 
    has_many :tags, :through => :link_tags 
    has_many :link_tags 

    accepts_nested_attributes_for :tags, :allow_destroy => :false, 
    :reject_if => proc { |attrs| attrs.all? { |k, v| v.blank? } } 
end 

class Tag < ActiveRecord::Base 
    has_many :links, :through => :link_tags 
    has_many :link_tags 
end 

class LinkTag < ActiveRecord::Base 
    belongs_to :link 
    belongs_to :tag 
end 

Acciones links_controller:

def new 
    @link = @current_user.links.build 
    respond_to do |format| 
     format.html # new.html.erb 
     format.xml { render :xml => @link } 
    end 
    end 

    def create 
    @link = @current_user.links.build(params[:link]) 

    respond_to do |format| 
     if @link.save 
     flash[:notice] = 'Link was successfully created.' 
     format.html { redirect_to links_path } 
     format.xml { render :xml => @link, :status => :created, :location => @link } 
     else 
     format.html { render :action => "new" } 
     format.xml { render :xml => @link.errors, :status => :unprocessable_entity } 
     end 
    end 
    end 

vista de código de new.html.erb:

<% form_for [current_user, @link], :url => account_links_path do |f| %> 
<%= render :partial => "form", :locals => { :f => f } %> 
<% end %> 

y de los parciales correspondientes:

<%= f.error_messages %> 

    <p> 
    <%= f.label :uri %><br /> 
    <%= f.text_field :uri %> 
    </p> 
    <p> 
    <%= f.label :title %><br /> 
    <%= f.text_field :title %> 
    </p> 

    <h2>Tags</h2> 
    <% f.fields_for :tags_attributes do |tag_form| %> 
    <p> 
    <%= tag_form.label :name, 'Tag:' %> 
    <%= tag_form.text_field :name %> 
    </p> 
    <% unless tag_form.object.nil? || tag_form.object.new_record? %> 
    <p> 
    <%= tag_form.label :_delete, 'Remove:' %> 
    <%= tag_form.check_box :_delete %> 
    </p> 
    <% end %> 
    <% end %> 

    <p> 
    <%= f.submit 'Update' %> 
    </p> 

La siguiente línea de código, en la acción de crear en el controlador de Enlace genera un error:

@link = @current_user.links.build(params[:link]) 

El error: Tag(#-621698598) expected, got Array(#-609734898)

¿Hay pasos adicionales necesarios en el has_many =>: a través de caso? Estos parecen ser los únicos cambios indicados para el caso básico de has_many.

+0

Soy incapaz de reproducir el problema basado en el código que has publicado. Podría publicar las partes de la asociación (líneas has_many/belongs_to/etc) de sus tres modelos, tanto las acciones relevantes del controlador (enlaces # nuevo, enlaces # crear) como cualquier código de vista que tenga que ver con el formulario de enlaces. – EmFi

+0

He agregado el código para las asociaciones, las acciones del controlador y las vistas. Gracias por tu ayuda. –

Respuesta

1

Prueba esto:

<% f.fields_for :tags_attributes do |tag_form| %> 
+1

error diferente ahora: 'método no definido 'with_indifferent_access' para "Codificación" String' Parámetros: {=> "fwCGGgcTKOSfxpFJMXmq7IUfRtfOvdOKl31Xys4TKC8 =" enlace "comprometerse"=> "Actualizar", "authenticity_token" " "=> {" tags_attributes "=> {" name "=>" Coding "}, " uri "=>" http://stackoverflow.com ", " title "=>" Desbordamiento de pila "}} Gracias por la sugerencia. ¿Hay una solución para esto? ¿Está tratando de tratar el valor de uno de los atributos como un hash? –

+0

¿Hay alguna manera de obtener el formato correcto para ese lío? –

+0

Puede pegar todo el formulario – obiwanchinobi

0

En su controlador en la nueva acción (que carga el formulario parcial), están construyendo un @tag través de su enlace?

Así debería ver algo en la línea de:

@link = Link.new 
@tag = @link.tags.build 

Podría ser mejor para fijar el contenido de la nueva y crear acción de su links_controller.

+0

Las acciones del controlador ahora están en la publicación original. No estoy creando la etiqueta en la nueva acción. Estaba siguiendo junto con la sección de modelos múltiples aquí: http://guides.rubyonrails.org/getting_started.html, que no indicaba que los cambios del controlador serían necesarios. Dicho esto, el nuevo formulario genera automáticamente un cuadro de etiqueta, a pesar de la ausencia de etiquetas. –

2

Para que esto funcione, es necesario pasar de hash de la derecha params:

params = { 
    :link => { 
    :tags_attributes => [ 
     {:tag_one_attr => ...}, {:tag_two_attr => ...} 
    ], 
    :link_attr => ... 
    } 
} 

Y su controlador se verá así:

def create 
    @link = Link.create(params[:link]) # this will automatically build the rest for your 
end 
0

tratar

<% f.fields_for :tags do |tag_form| %> 

(es decir, perder los _attributes en: tag_attributes) Así es como he hecho generalmente los formularios anidados

0

Es necesario construir una etiqueta en el controlador o en la vista

def new 
    @link = @current_user.links.build 
    @link.tags.build 
end 

#in your view you can just use the association name 
<% f.fields_for :tags do |tag_form| %> 
7

Echa un vistazo a la línea de su código

<% f.fields_for :tags_attributes do |tag_form| %> 

Es necesario utilizar simplemente :tags en lugar de :tags_attributes. Esto va a resolver su problema

Asegúrese de que usted tiene construir enlaces y etiquetas en su controlador como

def new 
    @link = @current_user.links.build 
    @link.tags.build 
end 
Cuestiones relacionadas