Rails: фильтрация на основе вычисления атрибутов дочернего элемента и родителя
У меня есть 2 связанные таблицы, и я хотел бы применить фильтр на основе атрибута длины футболки (дочерней таблицы), который составляет +/- %5 от родительского объекта.
К сожалению, я получаю неопределенную ошибку метода для имени родительской таблицы.
DB TABLES:
Student
------
id
name
height
Tshirt
------
id
color
student_id
length
МОДЕЛИ:
class Student < ApplicationRecord
has_many :tshirts
class Tshirt < ApplicationRecord
belongs_to :student
def self.suitablesize
joins(:student).where('length < ? AND length > ?', (1.05*self.student.height),(0.95*self.student.height))
end
контроллер:
def index
@tshirts = Tshirt.all.suitablesize
end
Сообщение об ошибке:
undefined method `student' for #<Class:0xc88cdc0>
РЕДАКТИРОВАТЬ: Я хотел бы получить все футболки, которые подходят для владельца студента (ов). Следовательно, я не хочу найти одного студента, который будет входным параметром для метода области. У вас есть идеи, как я могу решить эту проблему?
1 ответ
Объяснение ошибки
Ты звонишь student
на Tshirt
класс, хотя это мгновенный метод:
joins(:student).where('length < ? AND length > ?', (1.05*self.student.height),(0.95*self.student.height))
Вот self.student
это оскорбительная часть.
Вариант 1: рубашки одного студента
Если вы хотите учесть рост учащегося, вам придется изменить метод контекста, чтобы получить параметр:
def self.suitablesize(student)
where('length < ? AND length > ?', (1.05*student.height),(0.95*student.height))
end
А затем предоставьте студенту в вашем методе контроллера
def index
@tshirts = Tshirt.suitablesize([SOME STUDENT INSTANCE])
end
Часть, где я вставил [SOME STUDENT INSTANCE]
должен быть экземпляр ученика, который был, например, извлечен с помощью параметра, предоставленного запросом перед
def index
@student = Student.find(params[:id])
@tshirts = Tshirt.suitablesize(@student)
end
Точный параметр зависит от вашего приложения (среди прочего, от маршрутов), поэтому я могу предложить только общие указатели.
Вариант 2: рубашки всех студентов
Если не желательно подбирать подходящие рубашки для отдельного студента, нужно будет поместить расчеты в базу данных:
def self.suitable_size
joins(:student)
.where('tshirts.length < 1.05 * students.height AND tshirts.length > 0.95 * students.height')
end
После этого будут возвращены все футболки, принадлежащие студенту, где длина футболок составляет +/- 5% от роста студентов.