2013-10-07 5 views
6

Ho pubblicato una domanda precedente su questo e mi è stato consigliato di leggere molte informazioni rilevanti. Ho letto e provato a implementare circa 30 diverse soluzioni. Nessuno dei quali ha funzionato per me.Assolutamente bloccato cercando di creare un'associazione nidificata in forma di binari con has_many attraverso

Ecco cosa ho.

Ho un modello di miniature. Ho un modello Costruttori. Le miniature hanno molti produttori ATTRAVERSO un modello Productions.

Le associazioni sembrano essere configurate correttamente in quanto posso mostrarle nelle mie viste e crearle tramite la console. Dove ho un problema è lasciare che le miniature NEW e EDIT possano creare e aggiornare la tabella Productions.

Nella console il comando @miniature.productions.create(manufacturer_id: 1) funziona, il che mi porta a credere che dovrei essere in grado di fare lo stesso in una forma.

PENSO che il mio problema sia sempre nel controller Miniature e in particolare nella funzione CREA. Ho provato un sacco di altre soluzioni per la gente lì e nessuno ha fatto il trucco. È anche possibile che il mio campo_per cose nella mia forma sia sbagliato ma che sembra meno laborioso.

Sono stato bloccato su questo per giorni e mentre ci sono altre cose su cui potrei lavorare, se questa associazione non è possibile, allora avrei bisogno di ripensare la mia intera applicazione.

Il modulo ora crea una linea nella tabella Productions ma non include l'important_produttore.

Qualsiasi aiuto MOLTO apprezzato.

Il mio nuovo modulo in miniatura

<% provide(:title, 'Add miniature') %> 
<h1>Add a miniature</h1> 

<div class="row"> 
    <div class="span6 offset3"> 
    <%= form_for(@miniature) do |f| %> 
     <%= render 'shared/error_messages', object: f.object %> 
     <%= f.label :name %> 
     <%= f.text_field :name %> 
     <%= f.fields_for :production do |production_fields| %> 
     <%= production_fields.label :manufacturer_id, "Manufacturer" %> 
     <%= production_fields.select :manufacturer_id, options_from_collection_for_select(Manufacturer.all, :id, :name) %> 
     <% end %> 
     <%= f.label :release_date %> 
     <%= f.date_select :release_date, :start_year => Date.current.year, :end_year => 1970, :include_blank => true %> 

     <%= f.submit "Add miniature", class: "btn btn-large btn-primary" %> 
    <% end %> 
    </div> 
</div> 

Miniatures regolatore

class MiniaturesController < ApplicationController 
    before_action :signed_in_user, only: [:new, :create, :edit, :update] 
    before_action :admin_user,  only: :destroy 

    def productions 
    @production = @miniature.productions 
    end 

    def show 
    @miniature = Miniature.find(params[:id]) 
    end 

    def new 
    @miniature = Miniature.new 
    end 

    def edit 
    @miniature = Miniature.find(params[:id]) 
    end 

    def update 
    @miniature = Miniature.find(params[:id]) 
    if @miniature.update_attributes(miniature_params) 
     flash[:success] = "Miniature updated" 
     redirect_to @miniature 
    else 
     render 'edit' 
    end 
    end 
    def index 
    @miniatures = Miniature.paginate(page: params[:page]) 
    end 

    def create 
    @miniature = Miniature.new(miniature_params) 
    if @miniature.save 
     @production = @miniature.productions.create 
     redirect_to @miniature 
    else 
     render 'new' 
    end 
    end 

    def destroy 
    Miniature.find(params[:id]).destroy 
    flash[:success] = "Miniature destroyed." 
    redirect_to miniatures_url 
    end 

private 
    def miniature_params 
     params.require(:miniature).permit(:name, :release_date, :material, :scale, :production, :production_attributes) 
    end 

    def admin_user 
     redirect_to(root_url) unless current_user.admin? 
    end 

    def signed_in_user 
     unless signed_in? 
     store_location 
     redirect_to signin_url, notice: "Please sign in." 
     end 
    end 
end 

Modello miniatura

class Miniature < ActiveRecord::Base 
    has_many :productions, dependent: :destroy 
    has_many :manufacturers, :through => :productions 
    accepts_nested_attributes_for :productions 

    validates :name, presence: true, length: { maximum: 50 } 
    validates :material, presence: true 
    validates :scale, presence: true 
    validates_date :release_date, :allow_blank => true 

    def name=(s) 
    super s.titleize 
    end 

end 

modello di produzione

class Production < ActiveRecord::Base 
    belongs_to :miniature 
    belongs_to :manufacturer 



end 

Modello Produttore

class Manufacturer < ActiveRecord::Base 
    has_many :productions 
    has_many :miniatures, :through => :productions 
    validates :name, presence: true, length: { maximum: 50 } 
    accepts_nested_attributes_for :productions 
end 
+1

non ho guardato attraverso questo ampiamente, ma avete un problema sulla vostra action create in cui la relazione viene costruire su '@ Miniature' (con la maiuscola 'm') invece di' @ miniatura' (minuscole 'm' con le corrispondenze della variabile di istanza @miniature) ... –

+0

Ah grazie per averlo notato. L'ho corretto e ha emesso un errore sulla falsariga di "Impossibile creare fino a dopo il salvataggio del genitore", quindi ho spostato la linea sotto la riga "if @ miniature.save". Ora crea la linea nella tabella Productions ma non riempie il campo manufacturer_id. Sono stato qui prima, purtroppo. – Ossie

risposta

8

Invece di chiamare:

@production = @miniature.productions.create 

provare il Metodo Rails' "costruire":

def new 
    @miniature = Miniature.new(miniature_params) 
    @miniature.productions.build 
end 

def create 
    @miniature = Miniature.new(miniature_params) 
    if @miniature.save 
    redirect_to @miniature 
    else 
    render 'new' 
    end 
end 

L'utilizzo del metodo build utilizza la funzionalità di associazione automatica di ActiveRecord.

Vedi http://api.rubyonrails.org/classes/ActiveRecord/AutosaveAssociation.html

È inoltre necessario aggiornare il metodo di params, per esempio

def miniature_params 
    params.require(:miniature).permit(:name, :release_date, :material, :scale, productions_attributes: [:manufacturer_id]) 
end 

Anche il tuo fields_for dovrebbe essere plurale (credo) ...

<%= f.fields_for :productions do |production_fields| %> 
+0

Sì, questo mi consente di spostare la linea sopra la riga "if @miniature save" ma funziona lo stesso. Ottengo una nuova riga nella tabella ma non contiene il manufacturer_id. Deve essere che ho bisogno di comporre il mio modulo in modo diverso o ho bisogno di forzare il controller per usare quel particolare parametro. Oof. – Ossie

+0

Ho provato varie combinazioni nel bit params. Sembra fantastico ma non passa ancora il manufacturer_id alle produzioni. È molto possibile vero? – Ossie

+1

Puoi dire dal tuo log se passa il parametro, ma viene filtrato? O non sta passando affatto? Scusa se non sono stato di troppo aiuto, cerco di non usare moduli annidati a favore dell'uso di oggetti modulo ... Controlla il modello n. 3 su Oggetti modulo, qui: http://blog.codeclimate.com/blog/2012/10/17/7-way-to-decompose-fat-activerecord-models/ –

Problemi correlati