Страницы

Поиск по вопросам

суббота, 15 июня 2019 г.

Rails: scope из модели в self

Я получаю фильтр фильмов путем присваивания @movies нового значения, но я хотел бы чтобы возвращало в self и кусок кода @movies = @movies.filter_ratings(params[:ratings]) стал красивым: @movies.filter_ratings(params[:ratings])
Рою гугл 2 день, помогите пожалуйста!
Мой контроллер:
class MoviesController < ApplicationController def index @movies = Movie.sort_by(params[:sort_by]) @movies = @movies.filter_ratings(params[:ratings]) unless (params[:ratings]).nil? end end
Моя модель:
class Movie < ActiveRecord::Base # сортируем по требуемому полю scope :sort_by, ->(sorting) { all.order(sorting) } # выводим список рейтингов scope :all_ratings, -> { all.map{|movie| movie.rating }.uniq } # получаем фильмы согласно фильтру пользователя scope :filter_ratings, ->(filters) { where(:rating => filters.each_key.to_a) } end


Ответ

В ActiveRecord нет методов (публичных как минимум), меняющих уже созданный Relation
Так задумано (см. комментарии к этому коммиту в Rails). API построителя запросов задуман, как иммутабельный, чтобы он был более предсказуемым, не вызывал неожиданного поведения где-то, где это не указано явно.
Но я не вижу ни единой причины, по которой unless (params[:ratings]).nil? нельзя проверять в самом скоупе, возвращая self, если изменения не требуются:
scope :filter_ratings, ->(filters) { if filters.nil? self else where(:rating => filters.each_key.to_a) end }
Тогда сделать описанный вами запрос можно с помощью более длинной цепочки:
@movies = Movie.sort_by(params[:sort_by]).filter_ratings(params[:ratings])
Переносы/отступы по вкусу.

Комментариев нет:

Отправить комментарий