В Rails, как бы вы объединили два разных has_manys в одно?
Допустим, у нас есть пользователь.
Пользователь has_many документы через аккаунт, как это...
class User < ActiveRecord::Base
belongs_to :account
has_many :documents, :through => :account, :order => "created_at DESC"
end
class Account < ActiveRecord::Base
has_one :owner, :class_name => "User", :dependent => :destroy
has_many :documents, :dependent => :destroy
end
class Document < ActiveRecord::Base
belongs_to :account
end
Красиво и просто, вот где все становится сложнее...
Пользователь также может совместно работать над документами, это через объединенную таблицу соавторов...
class Collaborator < ActiveRecord::Base
belongs_to :user
belongs_to :documnet
end
class Document < ActiveRecord::Base
has_many :collaborators, :dependent => :destroy
has_many :users, :through => :collaborators
accepts_nested_attributes_for :collaborators, :allow_destroy => true
end
Последний бит пользователя - это то, в чем я не уверен. Я хочу добавить, что у другого есть много документов, и когда вы вызываете user.documents, он объединяет оба документа через свою учетную запись и те, с которыми они сотрудничают...
class User < ActiveRecord::Base
belongs_to :account
has_many :documents, :through => :account, :order => "created_at DESC"
#documents need to do both has manys…
has_many :collaborators, :dependent => :destroy
has_many :documents, :through => :collaborators
end
Спасибо, это немного долго, но я могу придумать изящное решение. Любая помощь приветствуется.
1 ответ
Вы можете создать метод, который будет запрашивать таблицы documents
, accounts
а также collaborators
найти документы, относящиеся к пользователю:
class User < ActiveRecord::Base
#...
def documents
Document.includes(:account, :collaborators).where('collaborators.user_id = ? OR documents.account_id = ?', self.id, self.account.id)
end
end
Я не проверял этот запрос, но надеюсь, вы поняли идею. Пожалуйста, исправьте это, если это ошибочно.
Для 2 has_many documents, :through...
вы можете удалить их, если они вам больше не нужны; В противном случае вы должны дать им разные имена (и отличаться от описанного выше метода).