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惯例,它将是pluralbillmethods.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