2017-09-26 93 views
0

我有2个关联的表,并希望应用基于父对象的+/-%5的tshirts(子表)长度属性的过滤器学生的高度属性Rails:基于父母的属性计算

不幸的是,我收到父表名的未定义方法错误。

DB表:

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> 

编辑: 我想得到适合所有者学生适用的所有t恤。因此,我不想找到一个学生作为范围方法的输入参数。你有什么想法我可以解决这个问题吗?

+1

你不需要使用'Tshirt.all.suitablesize'。 'Tshirt.suitablesize'就够了,因为它已经返回一个ActiveRecord作用域,因此'all'是一个NoOp。 – ulferts

回答

2

解释为错误

您正在呼吁Tshirtstudent,虽然它是一个即时的方法:

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 

通过由该请求提供的参数检索到的确切参数取决于你的应用程序(在其他事中routes),所以我只能提供一般的指针。

选项2:所有学生的衬衫

如果不希望找到合适的衬衫个别学生一个人必须要计算放到数据库:

def self.suitable_size 
joins(:student) 
    .where('tshirts.length < 1.05 * students.height AND tshirts.length > 0.95 * students.height') 
end 

这然后返回属于学生的所有衬衫,其中衬衫长度是学生身高的+/- 5%。

+0

感谢您的明确解释。我想获得适合所有者学生的所有适合的T恤衫。因此,我不想找到一个学生作为示波器方法的输入参数 – Tolga

+0

@Tolga我更新了答案,其中包含了关于如何找到所有衬衫的部分,而不仅仅是一个学生的衬衫 – ulferts