Объединение двух областей приводит к NoMethodError (неопределенный метод `default_scoped? '...) - PullRequest
2 голосов
/ 12 декабря 2011

Я определил следующие две области и обе работают нормально:

scope :regular_friends, lambda { |user| joins{friendships}.where{friendships.user_id.not_in(user)}}
scope :inverse_friends, lambda { |user| joins{inverse_friendships}.where{inverse_friendships.friend_id.not_in(user)}}

Я использую squeel (https://github.com/ernie/squeel) здесь и создаю самоссылочную ассоциацию, которая вдохновлена ​​(http://railscasts.com/episodes/163-self-referential-association).

Исходя из этого, я хочу определить третью область, которая объединяет результаты двух других:

scope :friends, lambda { |user| User.regular_friends(user).union(User.inverse_friends(user)) }

К сожалению, это не работает. Я получаю:

NoMethodError (undefined method `default_scoped?' for #<Arel::Nodes::Union:0x8249534>):

Я на Rails 3.1.3 . Я думал, что метод default_scope? был удален в Rails 3. *, но он жалуется на это ...

Кто-нибудь может помочь?

Ответы [ 2 ]

3 голосов
/ 26 декабря 2011

default_scope? действительно удаляется из Rails 3 и более поздних версий.Я не знаю, почему эта ошибка появляется (у меня та же проблема), но использование union() в областях, кажется, не работает.Использование их напрямую (за пределами scope), кажется, работает:

User.regular_friends(user).union(User.inverse_friends(user))

Лично я не помещаю объединение в область и использую его напрямую (к счастью, я использую его только в одном месте, поэтому для меняэто не имеет большого значения).

Я также не могу использовать union() напрямую с find(), first(), all() и т. д. Я думаю, arel еще нетзавершено ... Чтобы обойти эту проблему, я использую:

sql = User.regular_friends(user).union(User.inverse_friends(user)).to_sql
result = find_by_sql(sql)

Но, возможно, / возможно, есть более хорошие способы предотвратить это ...?(как ожидание обновления арла: P)

3 голосов
/ 12 декабря 2011

В Rails нет такого метода, как union (я не знаю об Arel). Просто создайте прицел, как обычно.

EDIT : Вы всегда можете использовать raw sql в определении объема. Я не знаю деталей вашего приложения (особенно того, как таблицы связаны), поэтому я не могу построить запрос во всей его красе. Тем не менее, запрос будет выглядеть примерно так:

scope :friends, find_by_sql(%(
  SELECT users.* FROM users INNER JOIN friendships f on f.user_id = users.#{id} WHERE ...
  UNION
  SELECT users.* FROM users INNER JOIN inverse_friendships i on i.friend_id = users.#{id} WHERE ...
)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...