Rails 连接并包含连接表中的列 [英] Rails Joins and include columns from joins table

查看:18
本文介绍了Rails 连接并包含连接表中的列的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我不明白如何从 rails 获取我想要的列.我有两个模型 - 一个用户和一个配置文件.用户 :has_many 个人资料(因为用户可以恢复到其个人资料的早期版本):

I don't understand how to get the columns I want from rails. I have two models - A User and a Profile. A User :has_many Profile (because users can revert back to an earlier version of their profile):

> DESCRIBE users;
+----------------+--------------+------+-----+---------+----------------+
| Field          | Type         | Null | Key | Default | Extra          |
+----------------+--------------+------+-----+---------+----------------+
| id             | int(11)      | NO   | PRI | NULL    | auto_increment |
| username       | varchar(255) | NO   | UNI | NULL    |                |
| password       | varchar(255) | NO   |     | NULL    |                |
| last_login     | datetime     | YES  |     | NULL    |                |
+----------------+--------------+------+-----+---------+----------------+

 

> DESCRIBE profiles;
+----------------+--------------+------+-----+---------+----------------+
| Field          | Type         | Null | Key | Default | Extra          |
+----------------+--------------+------+-----+---------+----------------+
| id             | int(11)      | NO   | PRI | NULL    | auto_increment |
| user_id        | int(11)      | NO   | MUL | NULL    |                |
| first_name     | varchar(255) | NO   |     | NULL    |                |
| last_name      | varchar(255) | NO   |     | NULL    |                |
|      .                .          .      .       .             .       |
|      .                .          .      .       .             .       |
|      .                .          .      .       .             .       |
+----------------+--------------+------+-----+---------+----------------+

在 SQL 中,我可以运行查询:

In SQL, I can run the query:

> SELECT * FROM profiles JOIN users ON profiles.user_id = users.id LIMIT 1;
+----+-----------+----------+---------------------+---------+---------------+-----+
| id | username  | password | last_login          | user_id | first_name    | ... |
+----+-----------+----------+---------------------+---------+---------------+-----+
| 1  | john      | ******   | 2010-12-30 18:04:28 | 1       | John          | ... |
+----+-----------+----------+---------------------+---------+---------------+-----+

看看我如何将 BOTH 表的所有列连接在一起?但是,当我在 Rails 中运行相同的查询时,我没有得到我想要的所有列 - 我只从 Profile 中得到那些:

See how I get all the columns for BOTH tables JOINED together? However, when I run this same query in Rails, I don't get all the columns I want - I only get those from Profile:

# in rails console
>> p = Profile.joins(:user).limit(1)
>> [#<Profile ...>]
>> p.first_name
>> NoMethodError: undefined method `first_name' for #<ActiveRecord::Relation:0x102b521d0> from /Library/Ruby/Gems/1.8/gems/activerecord-3.0.1/lib/active_record/relation.rb:373:in `method_missing' from (irb):8
# I do NOT want to do this (AKA I do NOT want to use "includes")
>> p.user
>> NoMethodError: undefined method `user' for #<ActiveRecord::Relation:0x102b521d0> from /Library/Ruby/Gems/1.8/gems/activerecord-3.0.1/lib/active_record/relation.rb:373:in method_missing' from (irb):9

我想(有效地)返回一个对象,该对象同时具有 Profile 和 User 的所有属性.我不想 :include 用户,因为它没有意义.用户应该始终是最新配置文件的一部分,就好像它们是配置文件模型中的字段一样.我该如何实现?

I want to (efficiently) return an object that has all the properties of Profile and User together. I don't want to :include the user because it doesn't make sense. The user should always be part of the most recent profile as if they were fields within the Profile model. How do I accomplish this?

我认为这个问题与 Profile 模型没有 User 的属性有关...

I think the problem has something to do with the fact that the Profile model doesn't have attributes for User...

推荐答案

我认为您无法通过加入 Rails 加载用户和配置文件.我认为在早期版本的 Rails (< 2.1) 中,关联模型的加载是通过连接完成的,但效率不高.这里你有一些解释和其他材料的链接.

I don't think that you can load users and profiles with join in Rails. I think that in earlier versions of Rails ( < 2.1) loading of associated models was done with joins, but it was not efficient. Here you have some explanation and links to other materials.

因此,即使您明确表示要加入它,Rails 也不会将其映射到关联模型.因此,如果您说 Profile.whatever_here,它将始终映射到 Profile 对象.

So even if you explicite say that you want to join it, Rails won't map it to associated models. So if you say Profile.whatever_here it will always be mapped to Profile object.

如果你还想按照你说的做,那么你可以自己调用自定义sql查询并处理结果:

If you still want to do what you said in question, then you can call custom sql query and process results by yourself:

p = ActiveRecord::Base.connection.execute("SELECT * FROM profiles JOIN users ON profiles.user_id = users.id LIMIT 1")

并逐行获取结果:

p.fetch_row

它已经是一个数组的映射.

It will already be mappet to an array.

您的错误是因为您在 AciveRecord::Relation 对象上调用了 first_nameuser 方法,并且它存储了一个 数组Profile 对象,而不是单个对象.所以

Your errors are because you are calling first_name and user method on AciveRecord::Relation object and it stores an array of Profile objects, not a single object. So

p = Profile.joins(:user).limit(1)
p[0].first_name

应该可以.

只获取一条记录的更好方法是调用:

Better way to fetch only one record is to call:

p = Profile.joins(:user).first
p.first_name
p.user

但是当你调用 p.user 时,它会查询数据库.为了避免这种情况,您可以使用include,但是如果您只加载一个配置文件对象,则它是无用的.如果您一次加载多个配置文件并希望包含用户表,这将会有所不同.

But when you call p.user it will query database. To avoid it, you can use include, but if you load only one profile object, it is useless. It will make a difference if you load many profiles at a time and want to inlcude users table.

这篇关于Rails 连接并包含连接表中的列的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆