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!

War es hilfreich?

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 
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top