Ruby on Rails Ассоциации - PullRequest
2 голосов
/ 12 мая 2010

Сейчас я начинаю создавать свои сайты в Ruby on Rails вместо PHP.

Я легко освоил язык, но все еще не уверен на 100% в ассоциациях:)

У меня такая ситуация:

Модель пользователя

has_and_belongs_to_many :roles

Модель ролей

has_and_belongs_to_many :users

Модель журнала

has_and_belongs_to_many :roles

Итак, у меня есть roles_users стол и journals_roles стол

Я могу получить доступ к ролям пользователя следующим образом:

user = User.find(1)
User.roles

Это дает мне роли, назначенные пользователю, и я могу получить доступ к модели журнала следующим образом:

journals = user.roles.first.journals

Это дает мне журналы, связанные с пользователем, на основе ролей. Я хочу иметь возможность доступа к журналам, как это user.journals

В моей пользовательской модели я пробовал это:

def journals
  self.roles.collect { |role| role.journals }.flatten
end

Это приводит меня к журналам в едином массиве, но, к сожалению, в этом случае я не могу получить доступ к чему-либо, связанному с журналами, например, в модели журналов:

has_many :items

Когда я пытаюсь получить доступ к user.journals.items, он не работает, так как это плоский массив, к которому я пытаюсь получить доступ к ассоциации has_many.

Можно ли получить user.journals другим способом, отличным от того, который я показал выше с помощью метода сбора?

Надеюсь, вы, ребята, понимаете, что я имею в виду, если не дадите мне знать, и я постараюсь объяснить это лучше.

Приветствия

Eef

Ответы [ 2 ]

1 голос
/ 12 мая 2010

Если вы хотите иметь user.journals, вы должны написать запрос от руки. Насколько я знаю, Rails связывает has_many :through ассоциации (habtm - своего рода has_many :through) на один уровень глубины. Вы можете использовать has_many с finder_sql.

user.journals.items в вашем примере не работает, потому что journals является массивом и с ним не связан метод items. Итак, вам нужно выбрать один журнал, а затем позвонить items:

user.journals.first.items

Я бы также изменил ваш journals метод:

def journals
  self.roles(:include => :journals).collect { |role| role.journals }.flatten.uniq
end

uniq удаляет дубликаты, а :inlcude => :journals должен улучшить sql запросы.

0 голосов
/ 12 мая 2010

Аналогичный вопрос /1428591/obedinenie-tablits-soedinenii-ruby-on-rails

Вы можете использовать Journal.scoped для создания области с необходимыми вам условиями. Поскольку у вас есть связь «многие ко многим» для ролей журналов, вам необходимо получить доступ к объединяющейся таблице либо с помощью отдельного запроса, либо с помощью внутреннего выбора:

  def journals
    Journal.scoped(:conditions => ["journals.id in (Select journal_id from journals_roles where role_id in (?))", role_ids])
  end

Тогда вы можете использовать user.journals.all(:include => :items) и т. Д.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...