Schienen has_many Durch Polymorphe Ankreuzfelder
-
25-09-2019 - |
Frage
Dies wird immer mir wirklich nach unten! :(
Ich versuche, eine verschachtelte Modellform für meine User-Modell mit einer Checkbox-Liste in zu machen, in denen mehrere Shops überprüft werden können oder nicht markieren die Shops durch Modell Staffing zu verwalten.
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
Für die Zwecke zur Hand die andere staffable Verein ignoriert werden kann. Es ist ein ähnliches Modell, dass ich schließlich neben Store verwalten wollen würde, aber erste, was der erste, da ich so ratlos bin, wie es ist.
# User Form
- for store in Store.all
%p
= check_box_tag "user[store_ids][]", store.id, @user.stores.include?(store)
= store.nickname
Sendet meine params entlang als solche:
{"utf8"=>"✓",
"authenticity_token"=>"blub-blub-blub=",
"user"=>{"login"=>"hey.buddy",
"email"=>"test@hey.net",
"role"=>"admin",
"hq"=>"1",
"password"=>"[FILTERED]",
"password_confirmation"=>"[FILTERED]",
"store_ids"=>["3",
"4"]}}
Und dann ERROR!
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)
Ich weiß, ich habe zu bauen staffable_type als ‚Store‘, aber ich habe den ganzen Tag versucht - was der Trick ist
?Ich habe tun, um die staffable_type (und id) Spalten auf. Null => false aber das kann nicht die Ursache dafür sein, wie diese Bedürfnisse in der Steuerung begradigt werden, bevor die DB sowieso schlagen
Warum wird die unten nicht Arbeit in meiner erstellen Aktion:
@user.staffings.each do |s|
s.staffable_type = 'Store'
end
oder:
@user.store_ids.each do |i|
s = @user.staffings.build
s.staffable_type = 'Store'
s.staffable_id = i
end
Wenn viele Dinge ähnlich wie die oben ohne Erfolg versucht. Jede Hilfe wäre massiv geschätzt.
Vielen Dank für Ihre Zeit!
Lösung
Okay, dachte ich, dieses heraus. Ich antworte hier so kann ich hoffentlich jemand eines Tages helfen, aber das Problem war ein einfaches Versehen auf den Unterschied zwischen vielen hat sich durch und hat, und gehört Viele Verbände.
Sie, wenn Sie Kontrollkästchen oder Mehrfachauswahl Listen behandeln möchten in ein Viele Durch Hat, gibt es keine ‚_ids‘ Methode für Sie durch die Assoziation erzeugt, und Sie müssen ein für sich selbst schreiben.
Siehe Paul Barry Artikel hier: http://paulbarry.com/articles/2007/10/24/has_many -durch-Kontrollkästchen
kann Polymorphe Sachen kompliziert sein, aber wenn Sie stecken wirklich gut vielleicht einen Schritt zurück und stellen Sie sicher, es ist nicht etwas noch Grund das bei Ihnen durcheinander up-- für mich gearbeitet!
Im Folgenden finden Sie den Code geändert von Paul Blog auf, wie dies umgehen, wenn man es zu tun mit einer polymorphen viele durch hat (im Grunde brauchen Sie nur die Attribute Hash zu verwenden und Ihre polymorphic_type Attribut schreiben):
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