2017-09-26 146 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