【问题标题】:Join normalized table with active record加入带有活动记录的规范化表
【发布时间】:2015-01-17 12:40:40
【问题描述】:

有一个customer 表,其中有idnameemail 列,还有一个address 表,其中有idstreetcodecustomer_id 列。

在 SQL 中,我使用以下方法加入两者:

SELECT c.id, c.name, c.email, a.street, a.code FROM customer AS c, address AS a WHERE a.customer_id = c.id;

在我建模的 Rails 中:

class Address < ActiveRecord::Base
    self.table_name = 'address'
end
class Customer < ActiveRecord::Base
    self.table_name = 'customer'

    has_one :address
end

在我尝试过的控制器中:

  • Customer.joins(:address) => SELECT customer.* FROM customer INNER JOIN address ON address.customer_id = customer.id
  • Customer.includes(:address) => SELECT customer.* FROM customer; SELECT address.* FROM address WHERE address.customer_id IN (1, 2)

但是两者都没有返回预期的结果。

如何获得与第一个 SQL 查询中定义的结果相同的结果,或者正确的方法是什么?

【问题讨论】:

    标签: ruby-on-rails rails-activerecord


    【解决方案1】:

    这不是完全正确的方式,但我了解您来自哪里,在完成大量数据库工作后学习了 Rails。运行控制台来测试这些想法。首先,地址正确地“属于”客户。客户“has_one”地址。这些在模型中定义。将模型视为数据库表。外键由您指定的这些关系定义。连接由关系解释。

    所以,在控制台中,创建一个地址。

    > Address.create(:street => "123 Main")
    

    输出将显示新地址的 ID。创建一条客户记录,并在 address_id 列中输入地址的 id。

    Customer.create(:address_id=> [ new address id ] )
    

    查询客户:

    > customer =  Customer.find([id number])
    

    然后,输入

    > customer.address
    

    它应该会显示地址。不需要加入(但它们发生在服务器上)。

    而且,您不需要在模型中指定表名。

    【讨论】:

    • 谢谢!你知道 ActiveRecord 是否使用延迟加载,因此它有时可能会隐藏属性?
    • 不客气!隐藏属性是什么意思?我相信延迟加载发生在“急切”加载中。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-06
    • 1970-01-01
    • 1970-01-01
    • 2023-03-14
    • 2011-11-27
    • 1970-01-01
    相关资源
    最近更新 更多