act_as_list с отношением has_and_belongs_to_many
Вопрос
Я нашел старый плагин act_as_habtm_list, но он для Rails 1.0.0.
Эта функция теперь встроена в act_as_list?Кажется, я не могу найти никакой информации об этом.
По сути, у меня есть таблица Artist_events — без модели.Отношения обрабатываются с помощью этих двух моделей, определяющих :has_and_belongs_to_many.
Как я могу указать порядок в этой ситуации?
Решение
Я предполагаю, что у вас есть две модели — «Исполнитель» и «Событие».
Вы хотите, чтобы между ними были отношения между ними, и вы хотите иметь возможность определять порядок событий для каждого исполнителя.
Вот мое решение.Я пишу этот код из головы, но в моем случае работает аналогичное решение.Я почти уверен, что есть возможности для улучшения.
Я использую плагин Rails act_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 должна иметь два внешних идентификатора и дополнительный столбец — Position.
Теперь вы можете использовать методы act_as_list (к сожалению, в модели ArtistEvent), но что-то вроде
Artist.find(:id).events
должен предоставить вам список событий, принадлежащих конкретному исполнителю, в правильном порядке.
Другие советы
Я пытаюсь с такой самореференцией
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 никогда не обновляется...
Идея ?
Обновлять:Хорошо, поле «id» необходимо в случае дополнительной модели с опцией has_many :through.Сейчас все работает хорошо
В принятом ответе обратите внимание, что :order => 'artist_events.position'
ссылается на таблицу artist_events
и не модель.
Я столкнулся с этим незначительным сбоем при переезде из habtm
ассоциация с has_many :through
.
Дополнительное обновление для исключенного ответа:для 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