В 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...вы можете удалить их, если они вам больше не нужны; В противном случае вы должны дать им разные имена (и отличаться от описанного выше метода).

Другие вопросы по тегам