ActiveRecord加入

时间:2014-04-06 21:29:19

标签: sql ruby-on-rails activerecord rails-activerecord

好的,如果我做User.joins(:session_users),我只获得用户表的属性。

如何以ActiveRecord方式获取两个表的属性,即不是SQL?

编辑一个

好的,基于第一个答案,我正试着让它显示出来。

因此,这是用户控制器中编写的方法

def blah 
  @users = User.includes(:session_users)
    @users.each do |user|
      user.session_users
    end
end 

然后我在用户视图中blah.html.erb

 <%= @users.session_users %> 

这在路由部分:

  match "/users/blah" => "users#blah"

2 个答案:

答案 0 :(得分:3)

我认为你想要includes而不是joins。有关详细信息,请参阅http://railscasts.com/episodes/181-include-vs-joins。这应该为两者提取列,

users = User.includes(:session_users)
users.each do |user|
  user.session_users
end

注意,这仍然执行2个SQL查询。

修改

更新后的答案假定user has_many :session_users

路线:

# config/routes.rb

get '/users/blah' => 'users#blah'

控制器:

# app/controllers/users_controller.rb

class UsersController < ApplicationController
  def blah
    @users = User.includes(:session_users)
  end
end

查看:

# app/views/users/blah.html.erb

<% @users.each do |user| %>

  <%= user.name %> // assumes user has a name attribute

  <% user.session_users.each do |session_user| %>
    <%= session_user.attributes %> // prints all the attributes
    <%= session_user.created_at %> // assumes the user has a created_at attribute
  <% end %>

<% end %>

答案 1 :(得分:0)

如果您确实需要将已连接表格中的字段添加到已设置的对象,则可以添加select

User.joins("INNER JOIN stolen_passwords
                    ON users.social_security_number=stolen_passwords.ssn")
    .select("*").find_each do |user|
      logger.debug { 
        "A #{user.full_name} has a password hash #{user.password_hash}" 
      }
end

此处,虚构的user.full_nameUser的实例方法,而user.password_hash来自stolen_passwords表。您还可以通过在select显式调用中列出查询/返回字段来限制查询/返回字段。

我们有时会在rake任务中使用它来丰富数据库或将其与第三方数据源进行比较:我们将使用提供的表连接我们的表,并使用两者中的列生成“并排”CSV。纯SQL也可以正常工作,但通过活动记录通常允许重用熟悉的范围或在ruby中执行计算的方法。

买者

不幸的是,来自连接表的字段将不会转换为适当的ruby类型,它们都将是字符串(如果使用joins的SQL字符串,这尤其合乎逻辑。但是很容易将连接的属性转换为:

module CastJoinedColumns
  def cast_joined_columns joined_record
    columns_hash.each do |column_name, column|
      if joined_record.attributes.include?(column_name)
        joined_record[column_name] = column.type_cast(joined_record[column_name])
      end
    end
  end
end

此模块旨在extended进入连接右侧出现的模型,并使用连接记录调用该方法。它可能会出错,并且应该针对多个表中出现相同列名的情况进行改进,但这是一个很好的起点(对于我们来说非常适合使用保证不与我们自己冲突的列名称的第三方数据源)。 p>