Обход HABTM отношений на ActiveRecord - PullRequest
0 голосов
/ 02 октября 2008

Я работаю над проектом для моей школы на рельсах (не волнуйтесь, это не оценка по коду), и я ищу чистый способ прохождения отношений в ActiveRecord.

У меня есть классы ActiveRecord, которые называются Пользователи, Группы и Назначения. Пользователи и группы имеют отношения HABTM, а также группы и назначения. Теперь мне нужна функция пользователя get_group (aid), в которой «дано пользователю, найти его группу по заданию».

Простой маршрут будет:

  def get_group(aid)
    group = nil
    groups.each { |g| group = g if g.assignment.find(aid).id == aid }
    return group
  end

Существует ли более чистая реализация, которая использует преимущества отношений HABTM между группами и назначениями, а не просто повторяется? Я также попробовал одну вещь: включить параметр для find (), например:

  def get_group(aid)
   user.groups.find(:first, 
     :include => :assignments, 
     :conditions => ["assignments.id = ?", aid])
  end

Но, похоже, это не работает. Есть идеи?

1 Ответ

3 голосов
/ 02 октября 2008

Прежде всего, будьте осторожны. Поскольку вы используете has_and_belongs_to_many для обоих отношений, то может быть более одного Group для данных User и Assignment. Поэтому я собираюсь реализовать метод, который возвращает массив Group s.

Во-вторых, имя метода User#get_group, принимающего идентификатор присваивания, довольно обманчиво и не похоже на Ruby.

Вот простой способ получить все общие группы, используя Array#& Руби, оператор пересечения. Я дал этому методу гораздо более откровенное имя и поместил его в Group, поскольку он возвращает Group экземпляров. Обратите внимание, однако, что он загружает Group с, которые связаны с одним, но не с другим:

class Group < ActiveRecord::Base
  has_and_belongs_to_many :assignments
  has_and_belongs_to_many :users

  # Use the array intersection operator to find all groups associated with both the User and Assignment 
  # instances that were passed in
  def self.find_all_by_user_and_assignment(user, assignment)
    user.groups & assignment.groups
  end
end

Тогда, если вам действительно нужен метод User#get_groups, вы можете определить его следующим образом:

class User < ActiveRecord::Base
  has_and_belongs_to_many :groups

  def get_groups(assignment_id)
    Group.find_all_by_user_and_assignment(self, Assignment.find(assignment_id))
  end
end

Хотя я бы, наверное, вместо этого назвал User#groups_by_assignment_id.

Моя Assignment модель просто:

class Assignment < ActiveRecord::Base
  has_and_belongs_to_many :groups
end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...