问题
I've found an old plugin called acts_as_habtm_list - but it's for Rails 1.0.0.
Is this functionality built in acts_as_list now? I can't seem to find any information on it.
Basically, I have an artists_events table - no model. The relationship is handled through those two models specifying :has_and_belongs_to_many
How can I specify order in this situation?
回答1:
I'm assuming that you have two models - Artist and Event.
You want to have an habtm relationship between them and you want to be able to define an order of events for each artist.
Here's my solution. I'm writing this code from my head, but similar solution works in my case. I'm pretty sure there is a room for improvement.
I'm using rails acts_as_list plugin.
That's how I would define models:
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
As you see you need an additional model ArtistEvent, joining the other two. The artist_events table should have two foreign ids and additional column - position.
Now you can use acts_as_list methods (on ArtistEvent model, unfortunately) but something like
Artist.find(:id).events
should give you a list of events belonging to specific artist in correct order.
回答2:
I trying with self-referencing like that
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
But the field cross_sales.position is never updated ...
An idea ?
Update: Ok the field 'id' it's necessary in the case of additional model with has_many :through option. It's work well now
回答3:
In the accepted answer, note that :order => 'artist_events.position'
is referencing the table artist_events
and not the model.
I ran into this minor hiccup when moving from a habtm
association to has_many :through
.
回答4:
Additional update for the excepted answer: for Rails 4 and Rails 5:
has_many :events, -> { order 'artist_events.position ASC' }, through: :artist_events
has_many :artists, -> { order 'artist_events.position ASC' }, through: :artist_events
来源:https://stackoverflow.com/questions/2274934/acts-as-list-with-has-and-belongs-to-many-relationship