Rails 有许多通过多态复选框

发布于 2024-10-02 16:09:14 字数 2557 浏览 4 评论 0原文

这真的让我很沮丧! :(

我正在尝试为我的用户模型创建一个嵌套模型表单,其中包含一个复选框列表,可以在其中选中或取消选中多个商店,以通过模型人员配置管理商店。

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

出于当前的目的,可以忽略其他可人员关联这是一个类似的模型,我最终想与 Store 一起管理,但首先是因为我很困惑,因为它是这样

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

发送我的参数:

{"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"]}}

错误!

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)

然后 Store',但我一整天都在尝试 - 有什么技巧吗?

我确实将 Staffable_type (和 id)列设置为 :null => false 但这不是原因,因为这需要纠正无论如何,在点击数据库之前,

创建操作中不起作用:

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

或者:

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

如果尝试了许多与上述类似的方法但没有成功,我们将不胜感激。

为什么下面的内容在我的

This one's really getting me down! :(

I'm trying to make a nested model form for my User model with a checkbox list in it where multiple Stores can be checked or unchecked to administer the Stores through model Staffing.

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

For the purposes at hand the other staffable association can be ignored. It's a similar model that I'd eventually want to administer alongside Store but first thing's first since I'm so stumped as it is.

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

Sends my params along as such:

{"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"]}}

And then 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)

I know I have to build out staffable_type as 'Store' but I've been trying all day--what's the trick?

I do have the staffable_type (and id) columns set to :null => false but that can't be the cause of this as this needs to be straightened out in the controller before hitting the DB anyway.

Why does the below not work in my create action:

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

or:

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

If been trying many things similar to the above to no avail. Any help would be massively appreciated.

Thanks for your time!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

み格子的夏天 2024-10-09 16:09:14

好吧,我想出了这个。我在这里回答是为了希望有一天能帮助别人,但问题是对“Has Many Through”和“Has And Belongs To Many Associations”之间差异的基本疏忽。

如果您想处理 Has Many Through 中的复选框或多选列表,则关联不会为您生成“_ids”方法,您需要自己编写一个方法。

请参阅保罗·巴里的文章:
http://paulbarry.com/articles/2007/10/24/has_many -through-checkboxes

多态的东西可能很复杂,但如果你真的陷入困境,也许退后一步,确保它不是更基本的东西让你陷入困境 - 对我有用!

下面是从 Paul 的博客中修改的代码,说明如果您正在处理多态性,如何处理这个问题(基本上您只需要使用属性哈希并编写您的 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 

Okay I figured this one out. I'm answering here so I can hopefully help someone someday, but the problem was a basic oversight on the difference between Has Many Through and Has And Belongs To Many Associations.

You if you want to handle checkboxes or multiselect lists in a Has Many Through, there is no '_ids' method generated for you by the association and you need to write one for yourself.

See Paul Barry's article here:
http://paulbarry.com/articles/2007/10/24/has_many-through-checkboxes

Polymorphic stuff can be complicated, but if you're stuck real good maybe take a step back and make sure it's not something even more basic that's messing you up-- worked for me!

Below is the code modified from Paul's blog on how to handle this if you're dealing with a polymorphic has many through (basically you just need to use the attributes hash and write your polymorphic_type attribute):

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 
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文