Rails 3: правильный синтаксис для named_scope с вызовом метода и ассоциациями модели

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

class User < ActiveRecord::Base
    has_many :comments
    has_many :geographies
    has_many :communities, through: :geographies

class Comment < ActiveRecord::Base
    belongs_to :user

class Community < ActiveRecord::Base
    has_many :geographies
    has_many :users

class Geography < ActiveRecord::Base
    belongs_to :user
    belongs_to :community

Пользователи могут публиковать комментарии, которые связаны с одним или несколькими сообществами через таблицу географии.

Моя задача — отображать только комментарии от сообщества, выбранного из выпадающего списка. Из этого сообщения я узнал, что могу получить доступ к сообщество данного комментария через цепочку объектов comment.user.communities.first.

Кажется, что обычно named_scope с лямбдой был бы предпочтительным выбором для фильтрации списка всех комментариев, однако я совершенно не понимаю, как построить этот named_scope. Я пытался построить named_scope, следуя некоторым RailsCast, но это все, что я смог сделать. Сгенерированная ошибка ниже.

class Comment < ActiveRecord::Base
    belongs_to :user

    def self.community_search(community_id)
        if community_id
            c = user.communities.first
            where('c.id = ?', community_id)
        else 
            scoped
        end
    end

    named_scope :from_community, { |*args| { community_search(args.first) } }

Это ошибка:

syntax error, unexpected '}', expecting tASSOC
named_scope :from_community, lambda { |*args|  { community_search(args.first) } }
                                                            ^

Каков правильный синтаксис для передачи метода с аргументами в named_scope?


person ntaj    schedule 03.07.2012    source источник


Ответы (1)


Во-первых, теперь вы можете просто использовать scope в rails 3 — старая форма named_scope была сокращена, и теперь она удалено в rails 3.1!

Однако, что касается вашей ошибки, я подозреваю, что вам не нужен внутренний набор скобок. Обычно они удваиваются при использовании такого лямбда-блока, потому что вы создаете новый хэш с нуля, например:

scope :foo, { |bar|
  { :key => "was passed #{bar}" }
}

Однако в вашем случае вы вызываете community_search, который должен возвращать значение, которое вы можете вернуть напрямую. В данном случае это объект AREL, заменивший такие простые хэши. Это несколько сбивает с толку при чтении всех случайных сообщений и руководств по этой теме, в основном из-за огромных изменений в стиле, которые вызвал AREL. Однако использование обоих этих стилей допустимо - либо как лямбда-метод, либо как метод класса. Они во многом означают одно и то же. В двух приведенных выше ссылках есть несколько примеров этого нового стиля для дальнейшего чтения.

Конечно, вы могли бы просто выучить что-то вроде squeel, который, как мне кажется, намного легче читать и вырезает много печатать. ^^;

person pdkl95    schedule 03.07.2012