如何使用has_many创建Rails4ActiveRecord模型,该模型使用OR条件联接自定义WHERE子句



我有一个正在使用的数据库结构,其中NodeInterviewees中的两个可能字段之一(clientnode_idcaregivernode_id)相关:

tbl_nodes
+----+-----------+
| id | node_Name |
+----+-----------+
|  5 | some name |
+----+-----------+
tbl_interviewees
+----+---------------+------------------+
| id | clientnode_id | caregivernode_id |
+----+---------------+------------------+
|  1 |             5 |             NULL |
+----+---------------+------------------+

我只是想在Node模型中定义一个has_many,其中包括来自任一字段的匹配项。等效的SQL是:

SELECT * FROM tbl_nodes LEFT JOIN tbl_interviewees ON (tbl_nodes.id=tbl_interviewees.clientnode_id OR tbl_nodes.id=tbl_interviewees.caregivernode_id)

我目前尝试了以下链接的建议,但没有成功(大多数使用不推荐使用的语法):

轨道3:在模型中使用带作用域的lambda

轨道具有动态条件(_Mny)

http://guides.rubyonrails.org/association_basics.html#belongs-到关联引用轨道具有多种条件(_M)

可能只是语法上的一些麻烦,所以任何帮助都将不胜感激。我知道这是错误的,但这是我最近的一次尝试:

class Node < ActiveRecord::Base
  self.table_name_prefix = :tbl_
  has_many :interviewees, -> { where("clientnode_id=? OR caregivernode_id=?", self.id, self.id) }
end

试试这个

@nodes = Node.joins(:interviewees).where("interviewees.clientnode_id=:node_id OR interviewees.caregivernode_id=:node_id", node_id: <your id>)

通过scope,在model 中写入带参数的范围

class Node < ActiveRecord::Base
  has_many :interviewees
  scope :interviews_by_node, ->(node_id) { joins(:interviewees).where("interviewees.clientnode_id=:node_id OR interviewees.caregivernode_id=:node_id", node_id: node_id)
end

调用controller动作中的scope

class NodesController < ApplicationController
  def index
    @nodes = Node.interviews_by_node(5)  
  end
end

我希望这会有所帮助。

@Nitin谢谢!我能够调整你的想法,得到我想要的行为如下:

class Node < ActiveRecord::Base
  # replaces using a "has_many :interviewees" since it is joined off 2 different fields
  def interviewees
    Interviewee.by_node(self.id)
  end
end
class Interviewee < ActiveRecord::Base
  # called by Node model to get Interviewee association
  scope :by_node, ->(node_id) { where("clientnode_id=? OR caregivernode_id=?", node_id, node_id) }
  # replaces "belongs_to :node" since it is joined off 2 different  fields
  def node
    Node.where("id = ? OR id = ?", self.clientnode_id, self.caregivernode_id)
  end
end

我觉得这样做有助于更好地保持封装,因为Node不应该知道受访者拥有的特定字段。

这使我可以使用相同的.node和.enabled方法名称并保持惯例。干杯

最新更新