【问题标题】:Rails - How to force associations to use alias table nameRails - 如何强制关联使用别名表名
【发布时间】:2013-12-23 05:48:44
【问题描述】:
p = Patient.find(30)

p.patient_problems

以上代码生成如下查询

SELECT `patient_problem`.* FROM `patient_problem` WHERE `patient_problem`.`patient_id` = 30 AND (`patient_problem`.`record_status_id` = 1)

但是有没有办法分配/使用别名 table_name 像

p.patient_problems(:alias=>'p1') # just for Ex.. This code will not work
p.patient_problems(:alias=>'p2') # just for Ex.. This code will not work

所以它会生成以下查询

SELECT `p1`.* FROM `patient_problem` AS `p1` WHERE `p1`.`patient_id` = 30 AND (`p1`.`record_status_id` = 1)

SELECT `p2`.* FROM `patient_problem` AS `p2` WHERE `p2`.`patient_id` = 30 AND (`p2`.`record_status_id` = 1)

其他信息

我的问题是当我尝试使用连接时

p.patient_problems(:all,:joins=>joins)

我收到此错误

ActionView::Template::Error (Mysql2::Error: Not unique table/alias: 'patient_problem': SELECT `patient_problem`.* FROM `patient_problem` LEFT OUTER JOIN party on party.id = patient_problem.patient_id 
        LEFT OUTER JOIN party_identifier on party.id = party_identifier.party_id
        LEFT OUTER JOIN blood_type on blood_type.id = party.blood_type_id
        LEFT OUTER JOIN education_level on education_level.id = party.education_level_id
        LEFT OUTER JOIN religion on religion.id = party.religion_id
        LEFT OUTER JOIN living_arrangement on living_arrangement.id = party.living_arrangement_id
      LEFT OUTER JOIN patient_problem patient_problem on patient_problem.patient_id = party.id and patient_problem.record_status_id = 1 
          left join (select user_type,username,user_id,auditable_id from (select MAX(id) id from audits where audits.auditable_type = 'PatientProblem' and user_type is not null group by auditable_id ) t inner join audits v on v.id=t.id ) entered_by1 on entered_by1.auditable_id = patient_problem.id
          left outer join user user1 on entered_by1.user_id = user1.id
          left outer join party as party_user1 on party_user1.id = user1.person_id
         LEFT OUTER JOIN patient_patient_search patient_patient_search1  on patient_patient_search1.patient_id = party.id
         left join search search1 on patient_patient_search1.patient_search_id = search1.id
         and patient_patient_search1.patient_search_id = '75' WHERE `patient_problem`.`patient_id` = 45 AND (`patient_problem`.`record_status_id` = 1) AND (  (patient_problem.occurrence_date > '2013-01-01 00:00:00' and patient_problem.occurrence_date < '2013-06-30 23:59:59' and   patient_problem.patient_problem_status_id in (5) and  patient_problem.code is not null and  patient_problem.code in ('10725009') )  and   (  patient_patient_search1.patient_search_id in (75.0) )  ))

当然,我可以对生成的连接查询进行一些字符串操作,并将别名设置为 Patient_problem。但我认为为关联设置别名会更清晰,因为生成的连接查询是不可预测的(在我的场景中)

【问题讨论】:

  • 为什么要给表名起别名?一定有更好的方法。
  • 因为我要附加一个巨大的连接查询(他们也有导致 unique table/alias 错误的患者问题)到上面的查询。
  • 我没有看到任何连接。是一对多吗?为什么生成的查询中有 id=71?解释你想要做什么。
  • 我很抱歉 id=71 是一个错字。我已经编辑了我想要做的事情

标签: mysql ruby-on-rails activerecord


【解决方案1】:

我不确定变量joins 是什么或它是如何构造的。要在连接中为表设置别名,请构建您的查询,例如

轨道 3

PatientProblem.joins("as p1 OUTER JOIN patient_problem as p2 on ...")

PatientProblem.find(:all, :joins => "as p1 OUTER JOIN patient_problem as p2 ON ...")

【讨论】:

  • 这只是给了我 ActiveRecord::StatementInvalid: PG::SyntaxError: ERROR: syntax error at or near "as"
  • @WylliamJudd,用于 Rails 4 语法检查 stackoverflow.com/a/19700056/643500
  • 我发现:“OUTER JOIN pateint_problem p1 on p1.item_id = items.id”
【解决方案2】:

您可以为此创建单例方法并编写一次查询并使用可能的时间

def self.p1
#your active record query here.
end 

然后像打电话一样

PatientProblem.p1

【讨论】:

  • 使用find_by_sql 可以做得更好,但这与别名关联无关
  • PatientProblem.p1p.patient_problems 完全不同,我也在寻找如何在运行时为关联设置别名表名
【解决方案3】:

更新

您可以简单地在代码中更改表名:

Patient.table_name="p2"

我不确定这是否会破坏其他任何东西......祝你好运!

原始答案

一种解决方案可能是为每种类型的 patient_problem 定义一个单独的模型,然后执行以下操作:

class PatientProblem2 < ActiveRecord::Base
 self.set_table_name "p2"
 ...
end

另一种解决方案可能是使用 ActiveRecord 查询接口,这将允许显着的查询灵活性: http://guides.rubyonrails.org/active_record_querying.html

也许您可以更具体地说明您要解决的自然问题。

【讨论】:

  • 表名还是patient_problem他只是想给它起别名
  • p2 是别名而不是表名
  • 这会导致SQL报错没有名为p2的表。
猜你喜欢
  • 2015-06-05
  • 1970-01-01
  • 2012-06-09
  • 1970-01-01
  • 1970-01-01
  • 2021-06-23
  • 2022-08-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多