5

Questo mi sta davvero facendo innamorare! :(Rails ha molte caselle di controllo Polymorphic

Sto cercando di fare un modello di formulario nidificato per il mio modello per l'utente con un elenco casella di controllo in esso, dove più negozi possono essere controllati o incontrollato di amministrare i negozi attraverso il modello di personale.

class Staffing < ActiveRecord::Base 
    # Associations 
    belongs_to :user 
    belongs_to :staffable, :polymorphic => true 
    belongs_to :store,  :class_name => "Store", 
         :foreign_key => "staffable_id" 
end 

class User < ActiveRecord::Base 
    # Includes 
    acts_as_authentic 

    # Associations 
    has_many :staffings, :dependent => :destroy 
    has_many :stores, :through => :staffings 

    # Nested Attributes 
    accepts_nested_attributes_for :staffings, :allow_destroy => true 
end 

class Store < ActiveRecord::Base 
    # Associations 
    has_many :staffings, :as => :staffable, :dependent => :destroy 
    has_many :users, :through => :staffings 
end 


# Users Controller 
def create 
    @user = User.new(params[:user]) 
    flash.now[:notice] = "#{@user.name} was successfully created." if @user.save 
    respond_with @user 
end 


def update 
    @user = User.find(params[:id]) 
    params[:user][:store_ids] ||= [] 
    @user.update_attributes(params[:user]) 
    flash.now[:notice] = "#{@user.name} was successfully updated." 
    respond_with @user 
end 

Per le finalità a portata di mano l'altra associazione staffable può essere ignorato. si tratta di un modello simile che avrei finalmente desidera amministrare al fianco Store, ma prima cosa di prima da quando sono così perplesso come è.

# User Form 
- for store in Store.all 
    %p 
    = check_box_tag "user[store_ids][]", store.id, @user.stores.include?(store) 
    = store.nickname 

mandate i miei params lungo come tale:

{"utf8"=>"✓", 
"authenticity_token"=>"blub-blub-blub=", 
"user"=>{"login"=>"hey.buddy", 
"email"=>"[email protected]", 
"role"=>"admin", 
"hq"=>"1", 
"password"=>"[FILTERED]", 
"password_confirmation"=>"[FILTERED]", 
"store_ids"=>["3", 
"4"]}} 

E quindi ERRORE!

Mysql2::Error: Column 'staffable_type' cannot be null: INSERT INTO `staffings` (`created_at`, `staffable_id`, `staffable_type`, `updated_at`, `user_id`) VALUES ('2010-11-17 00:30:24', 3, NULL, '2010-11-17 00:30:24', 102) 

so che devo costruire fuori staffable_type come 'Store', ma ho cercato per tutto il giorno - qual è il trucco?

Ho le colonne staffable_type (e id) impostate su: null => false ma questa non può essere la causa di questo in quanto è necessario che questo venga rettificato nel controller prima di colpire comunque il DB.

Perché il seguito non funziona nella mia azione creare:

@user.staffings.each do |s| 
    s.staffable_type = 'Store' 
end 

o:

@user.store_ids.each do |i| 
    s = @user.staffings.build 
    s.staffable_type = 'Store' 
    s.staffable_id = i 
end 

Se state cercando molte cose simili a quanto sopra senza alcun risultato. Qualsiasi aiuto sarebbe enormemente apprezzato.

Grazie per il vostro tempo!

risposta

4

Ok, l'ho capito. Sto rispondendo qui, quindi spero di poter aiutare qualcuno un giorno, ma il problema è stato un controllo di base sulla differenza tra Has Many Through e Has And Belongs To Many Associations.

Se si desidera gestire le caselle di controllo o gli elenchi di più selezioni in A Many Through, non esiste un metodo '_ids' generato dall'utente dall'associazione e è necessario scriverne uno per sé. articolo

vedere Paul di Barry qui: http://paulbarry.com/articles/2007/10/24/has_many-through-checkboxes

roba polimorfico può essere complicato, ma se sei bloccato vero bene forse fare un passo indietro e assicurarsi che non è qualcosa di ancora più fondamentale che si sta pasticciano up-- ha funzionato per me!

Di seguito si riporta il codice modificato dal blog di Paolo su come gestire questo se hai a che fare con un polimorfica ha molti attraverso (in pratica si solo bisogno di utilizzare l'hash attributi e scrivere l'attributo polymorphic_type):

attr_accessor :store_ids 
after_save :update_stores 

#after_save callback to handle group_ids 
def update_stores 
    unless store_ids.nil? 
    self.staffings.each do |staffing| 
     staffing.destroy unless store_ids.include?(staffing.staffable_id.to_s) 
     store_ids.delete(staffing.staffable_id.to_s) 
    end 
    store_ids.each do |s| 
     self.staffings.create(attributes = {:staffable_id => s, :staffable_type => 'Store'}) unless s.blank? 
    end 
    reload 
    self.store_ids = nil 
    end 
end