has_many: сквозное с class_name и foreign_key
Я работаю с довольно простой has_many: ситуация, когда я могу заставить параметры class_name / foreign_key работать в одном направлении, но не в другом. Возможно, вы можете помочь мне. (p.s. Я использую Rails 4, если это делает diff):
Английский: пользователь управляет многими листингами через ListingManager, а листингом управляют многие пользователи через ListingManager. Менеджер списков имеет несколько полей данных, не относящихся к этому вопросу, поэтому я отредактировал их в следующем коде
Вот простая часть, которая работает:
class User < ActiveRecord::Base
has_many :listing_managers
has_many :listings, through: :listing_managers
end
class Listing < ActiveRecord::Base
has_many :listing_managers
has_many :managers, through: :listing_managers, class_name: "User", foreign_key: "manager_id"
end
class ListingManager < ActiveRecord::Base
belongs_to :listing
belongs_to :manager, class_name:"User"
attr_accessible :listing_id, :manager_id
end
как вы можете догадаться сверху, таблица ListingManager выглядит так:
create_table "listing_managers", force: true do |t|
t.integer "listing_id"
t.integer "manager_id"
end
так что единственное непростое здесь это то, что ListingManager используетmanager_id
скорее, чемuser_id
Во всяком случае, вышесказанное работает. я могу позвонитьuser.listings
чтобы получить списки, связанные с пользователем, и я могу позвонитьlisting.managers
чтобы получить менеджеров, связанных с листингом.
Однако (и вот в чем вопрос) я решил, что не очень-тоuser.listings
так как пользователь также может «владеть», а не «управлять» списками, я действительно хотелuser.managed_listings
так что я подправилuser.rb
изменить has_many: списки, через:: list_managers на has_many: managed_listings, через:: list_managers, class_name: "Listing", foreign_key: "Listings_id"
Это точная аналогия с кодом вlisting.rb
выше, так что я подумал, что это должно сработать сразу. Вместо этого мой тест rspec этого barfs, сказавActiveRecord::HasManyThroughSourceAssociationNotFoundError: Could not find the source association(s) :managed_listing or :managed_listings in model ListingManager. Try 'has_many :managed_listings, :through => :listing_managers, :source => <name>'. Is it one of :listing or :manager?
тестом является:
it "manages many managed_listings" do
user = FactoryGirl.build(:user)
l1 = FactoryGirl.build(:listing)
l2 = FactoryGirl.build(:listing)
user.managed_listings << l1
user.managed_listings << l2
expect( @user.managed_listings.size ).to eq 2
end
Теперь я убежден, что ничего не знаю. Да, я думаю, что я мог бы сделать псевдоним, но меня беспокоит, что тот же метод, используемый вlisting.rb
не похоже на работу вuser.rb
, Вы можете помочь объяснить?
ОБНОВЛЕНИЕ: я обновил код, чтобы отразить предложения @gregates, но все еще сталкиваюсь с проблемой: я написал дополнительный тест, который не проходит (и подтверждается «ручным» тестированием в консоли Rails). Когда кто-то пишет такой тест:
it "manages many managed_listings" do
l1 = FactoryGirl.create(:listing)
@user = User.last
ListingManager.destroy_all
@before_count = ListingManager.count
expect( @before_count ).to eq 0
lm = FactoryGirl.create(:listing_manager, manager_id: @user.id, listing_id: l1.id)
expect( @user.managed_listings.count ).to eq 1
end
Выше не удается. Rails генерирует ошибкуPG::UndefinedColumn: ERROR: column listing_managers.user_id does not exist
(Это должно искать 'list_managers.manager_id'). Поэтому я думаю, что все еще есть ошибка на стороне пользователя ассоциации. Вuser.rb
«shas_many :managed_listings, through: :listing_managers, source: :listing
как пользователь знает, как использоватьmanager_id
попасть в свои списки?