我不明白如何从 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_name 和 user 方法,并且它存储了一个 数组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 连接并包含连接表中的列
发布评论