Можно ли условно связать области в Rails? - PullRequest
0 голосов
/ 17 декабря 2018

Рассмотрим этот код:

class Car
  scope :blue, -> { where(color: "blue") }
  scope :manual, -> { where(transmission: "manual") }
  scope :luxury, -> { where("price > ?", 80000) }
end

def get_cars(blue: false, manual: false, luxury: false)
  cars = Car.all
  cars = cars.blue if blue
  cars = cars.manual if manual
  cars = cars.luxury if luxury
end

Есть ли способ условно связать эти области, как Car.blue.manual.luxury?Т.е. только область, если аргумент истинен?

Ответы [ 2 ]

0 голосов
/ 17 декабря 2018

Вы можете использовать yield_self ( подробнее здесь ), для него добавлена ​​новая функциональность в ruby ​​2.5.

В вашем примере:

class Car
  scope :blue, -> { where(color: "blue") }
  scope :manual, -> { where(transmission: "manual") }
  scope :luxury, -> { where("price > ?", 80000) }
end

def get_cars(blue: false, manual: false, luxury: false)
  cars = Car.all
            .yield_self { |cars| blue ? cars.blue : cars }
            .yield_self { |cars| manual ? cars.manual : cars }
            .yield_self { |cars| luxury ? cars.luxury : cars }
end
0 голосов
/ 17 декабря 2018

Области ActiveRecord могут применяться условно, например так:

scope :blue, -> { where(color: 'blue') if condition }

Где condition - это то, что вы определяете, что возвращает истину или ложь.Если условие возвращает true, область применения применяется.Если условие ложно, область игнорируется.

Вы также можете передавать значения в область:

scope :blue, ->(condition) { where(color: 'blue') if condition }

Итак, вы можете сделать что-то вроде этого:

Task.blue(color == 'blue')

Что похоже на запрос OP.Но с чего бы это?

Лучший подход - это что-то вроде этого:

scope :color, ->(color) { where(color: color) if color.present? }

Что можно назвать так:

Car.color('blue')  # returns blue cars
Car.color(nil)     # returns all cars

Car.color(params[:color])  # returns either all cars or only cars of a specific color, depending on value of param[:color]

Car.color(params[:color]).transmission(params[:transmission]).price(params[:price])

Ваш пробег может отличаться.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...