Области и сферы применения рельсов

может кто-нибудь объяснить, что делает этот метод и что я могу передать ему?

scoped(options = nil)
Returns an anonymous scope.

а также что делает метод scope? Я не понимаю после прочтения документации.

2 ответов


в ActiveRecord все методы построения запросов (например,where, order, joins, limit и так далее) вернуть так называемый область. Только когда вы вызываете метод kicker, такой как all или first выполняется встроенный запрос и возвращаются результаты из базы данных.

на scoped class метод также возвращает область. Возвращаемая область по умолчанию пуста, что означает, что результирующий набор никоим образом не будет ограничен, то есть все записи будут возвращается при выполнении запроса. Вы можете использовать его для предоставления" пустой " альтернативы, как в query_by_date пример MurifoX. Или вы можете использовать его для объединения нескольких условий в один вызов метода, например:

Model.scoped(:conditions => 'id < 100', :limit => 10, :order => 'title ASC')

# which would be equivalent to
Model.where('id < 100').limit(10).order('title ASC')

на scope class method позволяет определить метод класса, который также возвращает область, например:

class Model
  scope :colored, lambda {|col|
    where(:color => col)
  }
end

который можно использовать следующим образом:

Model.colored

хорошая вещь с scopes заключается в том, что вы можете комбинировать их (почти) по своему желанию, поэтому абсолютно возможно следующее:

Model.red.where('id < 100').order('title ASC').scoped(:limit => 10)

я также настоятельно рекомендую прочитать http://guides.rubyonrails.org/active_record_querying.html


я использовал его в прошлом.Когда вы делаете прикованные вызовы ActiveRecord интерфейс запроса, как это:

Model.where(:conditions).where(:more_conditions).where(:final_conditions)

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

Model.query_by_date(date).query_by_user(user).query_by_status(status)

scope :query_by_date, lambda { |date|
  case date
  when "today"
    where(:date => Date.today)
  when "tomorrow"
    where(:date => Date.tomorrow)
  else
    # Any value like '' or 0 or Date.whatever
  end
}

это вызовет ошибку, если дата param не сегодня или завтра. Он выберет последнее значение и попытается связать этот запрос со следующим query_by_user, в результате чего undefined method default_scoped? for ''. Но если вы поставите scoped метод в else условие, это будет работать без каких-либо недостатков, потому что вы говорите activerecord, что вы проходите через этот метод/именованную область и не делали никаких вызовов where/find/other activerecord methods, но вернулся объект с областью видимости, поэтому вы можете продолжить цепочку запросов и прочее.
В конце концов так и будет.

else
  scoped
end

надеюсь, вы понимаете этот простой пример.