Rails 3: Как создать именованную область видимости на основе метода контроллера? - PullRequest
2 голосов
/ 20 мая 2011

В моем ApplicationController у меня есть метод demo_mode? (который возвращает true, когда в данный момент вошедшим в систему типом пользователя является "demo").

Модель

Post имеет поле publisher_id, которое относится к таблице Users.

User имеет поле user_type, одним из возможных значений которого является "demo".

Итог: сообщение p было опубликовано пользователем "demo" тогда и только тогда, когда:

User.find(p.publisher_id).user_type == "demo"

Я хотел бы создать именованную область действия Post.relevant, которая будет возвращать:

  • все сообщения, опубликованные пользователями "демо", если demo_mode? == true
  • все сообщения, которые были опубликованы не "демо" пользователями, если demo_mode? == false

Как бы вы создали такую ​​именованную область? Должен ли я переехать demo_mode? в другое место?

Ответы [ 3 ]

2 голосов
/ 20 мая 2011

Используйте лямбду, чтобы создать динамическую область, и сохраните информацию о сеансе вне модели:

В вашей модели:

class Post < ActiveRecord::Base
  scope :relevant, lambda {|demo_mode|
     joins(:publisher).
     where("publishers.user_type #{demo_mode ? '' : 'NOT'} LIKE 'demo'")
  }
end

А затем в контроллере:

posts = Post.relevant(demo_mode?)
0 голосов
/ 20 мая 2011

Если я правильно понимаю, демонстрационное состояние определяется сеансом, поэтому об этом знает только контроллер. С другой стороны, контроллер (или, возможно, представление) - это единственное место, где вы хотите запросить область. Если все это правильно, я бы добавил метод в ApplicationController следующим образом:

class ApplicationController < ActionController::Base
  def relevant_posts
    Post.joins(:publisher).
      where("publishers.user_type #{demo_mode? ? '' : 'NOT'} LIKE 'demo'")
  end

  ...
  helper_method :relevant_posts # if you want it to be available in views
end

Технически, это не именованная область. В Rails 3, однако, нет большой разницы между именованными областями и стандартным интерфейсом запросов.

0 голосов
/ 20 мая 2011

Попробуйте что-то вроде этого

class Post < ActiveRecord::Base

    scope :relevant, joins("INNER JOIN users ON (users.user_type = 'demo')").where("publisher_id = users.id")

end
...