具有has_and_belongs_to_many关系的acts_as_list

时间:2010-02-16 17:35:29

标签: ruby-on-rails ruby-on-rails-plugins has-and-belongs-to-many acts-as-list

我发现了一个名为acts_as_habtm_list的旧插件 - 但它适用于Rails 1.0.0。

这个功能现在是在acts_as_list中构建的吗?我似乎无法找到任何相关信息。

基本上,我有一个artists_events表 - 没有模型。通过指定的两个模型处理关系:has_and_belongs_to_many

如何在这种情况下指定顺序?

4 个答案:

答案 0 :(得分:22)

我假设你有两个模特 - 艺术家和事件。

您希望在他们之间建立habtm关系,并且您希望能够为每位艺术家定义事件顺序。

这是我的解决方案。我正在编写这个代码,但类似的解决方案适用于我的情况。我很确定还有改进的余地。

我正在使用rails acts_as_list插件。

这就是我定义模型的方式:

class Artist < ActiveRecord::Base
  has_many :artist_events
  has_many :events, :through => :artist_events, :order => 'artist_events.position'
end

class Event < ActiveRecord::Base
  has_many :artist_events
  has_many :artists, :through => :artist_events, :order => 'artist_events.position'
end

class ArtistEvent < ActiveRecord::Base
  default_scope :order => 'position'
  belongs_to :artist
  belongs_to :event
  acts_as_list :scope => :artist
end

如您所见,您需要一个额外的模型ArtistEvent,加入另外两个。 artist_events表应该有两个外部ID和附加列 - 位置。

现在你可以使用acts_as_list方法(不幸的是在ArtistEvent模型上),但是类似

Artist.find(:ID).events

应按正确的顺序为您提供属于特定艺术家的事件列表。

答案 1 :(得分:1)

我尝试使用自我引用

class Product < ActiveRecord::Base
  has_many :cross_sales
  has_many :cross_sales_products, :through => :cross_sales, :order => 'cross_sales.position'
end

class CrossSale < ActiveRecord::Base
  default_scope :order => 'cross_sales.position'
  belongs_to :product
  belongs_to :cross_sales_product, :class_name => "Product"
  acts_as_list :scope => :product
end

create_table :cross_sales, :force => true, :id => false do |t|
  t.integer :product_id, :cross_sales_product_id, :position
end

但字段cross_sales.position永远不会更新......

一个想法?

更新:如果使用has_many:through选项的附加模型,则需要字段'id'。它现在运作良好

答案 2 :(得分:0)

在接受的答案中,请注意:order => 'artist_events.position'引用的是表artist_events,而不是模型。

habtm关联转移到has_many :through时,我遇到了这种轻微的打嗝。

答案 3 :(得分:0)

针对例外答案的其他更新:适用于Rails 4和Rails 5:

has_many :events, -> { order 'artist_events.position ASC' }, through: :artist_events
has_many :artists, -> { order 'artist_events.position ASC' }, through: :artist_events