Rails模型使用连接写def
我正试图在“工作人员”的模型中为“可计费”建立一个def。
关系:
Workorders - belongs_to :billmethod Billmethod - has_many :workorders
我试过这些:
def self.billable joins(:billmethods).where(billmethods: {"method_name != ?", 'Not Billable'}) end def self.billable where("billmethod.method_name != ?", 'Not Billable') end
您需要使用与has_many / belongs_to中定义的名称相同的名称(但始终使用where()
方法中的复数名称:
如果:
class Workorder < ActiveRecord::Base belongs_to :billmethod # ^^
然后:
def self.billable joins(:billmethod).where('billmethods.method_name != ?', 'Not Billable') # ^^ end
如果:
class Workorder < ActiveRecord::Base has_many :billmethods # ^
然后:
def self.billable joins(:billmethods).where('billmethods.method_name != ?', 'Not Billable') # ^ end
根据您定义的associations
:
Workorders - belongs_to :billmethod Billmethod - has_many :workorders
模型应该是
class Workorder < ActiveRecord::Base belongs_to :billmethod ## Above line specifies the association of model "Billmethod" with "Workorder" ## It denotes that a workorder belongs_to a specific billmethod (exactly one) so billmethod must be singular here ## ... end class Billmethod < ActiveRecord::Base has_many :workorders ## Above line specifies the association of model "Workorder" with "Billmethod" ## It denotes that a billmethod has_many workorders (0 or more) so workorders must be plural here ## ... end
让我们首先浏览您在Workorder
模型中尝试过的代码以及为什么它不起作用:
第一次尝试:
def self.billable joins(:billmethods).where(billmethods: {"method_name != ?", 'Not Billable'}) end
问题1: joins(:billmethods)
如上所述,工作Workorder belongs_to billmethod
,因此您必须在此处传递billmethod
作为单数 。 否则,ActiveRecord将尝试查找名为billmethods
(复数)的billmethods
并引发错误
Association named billmethods was not found on Workorder
问题2: where(billmethods: {"method_name != ?", 'Not Billable'})
{"method_name != ?", 'Not Billable'}
应该是一个Hash
如: {key : value}
但它看起来像{something, something}
,它不是Hash
。
第二次尝试:
def self.billable where("billmethod.method_name != ?", 'Not Billable') end
问题1: No joining condition
您尚未指定连接条件,因此无法访问billmethods
表中的字段。
问题2: where("billmethod.method_name != ?", 'Not Billable')
您在此处使用了正确的语法。 但是,如问题1中所述,即上面No joining condition
,您将无法从billmethods
表访问字段method_name
。
这里的另一个问题是,在where
方法中,您应该使用数据库中存在的实际table name
。 根据Rails惯例,它将是plural
即billmethods.method_name
而不是billmethod.method_name
。
可能的解决方案:
您可以尝试以下几种可能的解决方案:
def self.billable joins(:billmethod).where('billmethods.method_name != ?', 'Not Billable') end
- 或者 - 对于Rails 4.x
def self.billable joins(:billmethod).where.not(billmethods: {method_name: "Not Billable"}) end
您也可以使用scope
代替类方法,例如:
class Workorder < ActiveRecord::Base belongs_to :billmethod scope :billable, ->(status) { joins(:billmethod).where('billmethods.method_name != ?', status) } ## ... end
然后,您可以将上面定义的范围称为
Workorder.billable("Not Billable")
status
将在范围查询中设置为Not Billable
。
如果您总是要搜索Not Billable
记录,请将范围更改为:
scope :billable, -> { joins(:billmethod).where("billmethods.method_name != 'Not Billable'") }
直接将此范围称为Workorder.billable
。