【问题标题】:Select multiple values from associated model rails从关联的模型导轨中选择多个值
【发布时间】:2015-01-04 21:27:22
【问题描述】:

假设我有这个关联

User have_many posts
Post belongs_to user

User   Post
----------------
id     id
name   title
       user_id

如何仅列出包含/加入的帖子标题和用户名?

(帖子列表 [标题 - 用户名])

@posts = Post.includes(:user).select('........')

不要提供这个

@posts = Post.all.each {|p| p.user.username}

__________________UP_____________________

它适用于连接 2 个表。

如果我想将它用于更复杂的示例怎么办?

查看我的上一个问题optimize sql query rails

@Humza 的回答部分有效。 可能是这样的

@posts = Post.joins(:user, :category).paginate(:page => params[:page]).order("created_at DESC")

但它不显示没有类别的帖子

我还需要显示 gravatar,但我认为我可以将 user.email 用作 usr_email 并使用 gravatar_for (post.usr_email),但我必须为此自定义 gravatar 助手。

posts_controller.rb

def index
  @posts = Post.includes(:user).includes(:comments).paginate(:page => params[:page]).order("created_at DESC")
end

index.html.erb

 <%= render @posts %>

_post.html.erb

<%= gravatar_for post.user, size:20 %>
<%= link_to "#{post.title}", post_path(post) %>
<%= time_ago_in_words(post.created_at) %> 
<%= post.comments.count %>
<%= post.category.name if post.category %>

【问题讨论】:

    标签: ruby-on-rails activerecord


    【解决方案1】:

    看看pluck

    Post.joins(:user).pluck(:title, :name)
    

    请注意,它在这种情况下有效,因为name 列没有歧义,您可能需要明确指定表 (pluck(:title, "users.name"))。

    【讨论】:

    • 它可以工作,但是在渲染 @posts ....is not an ActiveModel-compatible object 时出现错误。它必须实现 :to_partial_path。更新的问题。
    • 是的,pluck 总是返回一个普通的 Ruby 数组。
    【解决方案2】:

    includes 用于急切加载。在这种情况下,您需要 joins

    posts = Post.joins(:user).select("posts.title AS title, users.name AS username")
    

    您可以通过以下方式访问这些值:

    post = posts.first
    post.title # will give the title of the post
    post.username # will give the name of the user that this post belongs to
    

    如果您可以pluck 多列,那么以下内容可能对您更有用:

    posts = Post.joins(:user).pluck("posts.title", "users.name")
    

    结果将是一个二维数组,每个元素都是[post_title, post_username]形式的数组

    【讨论】:

    • 这对我来说有点用,但如果我有一个更复杂的关联怎么办。更新了我的问题。你能推荐任何关于连接的文章吗?谢谢!
    【解决方案3】:
    Post.joins(:user, :category)
    

    但它不显示没有类别的帖子

    这是因为joins 使用INNER JOIN 将表连接在一起。如果您想要来自Post 的所有内容,即使特定记录在另一个表中没有对应的记录,您需要使用LEFT JOIN。不幸的是,ActiveRecord 没有很好的生成方法,您需要手动完成:

    Post.joins("LEFT OUTER JOIN categories ON categories.post_id = posts.id")...
    

    更多信息请参见A Visual Explanation of SQL Joins

    【讨论】:

    • 你把我踢向了正确的方向)现在我有了这个: Post.joins(:user).joins("LEFT OUTER JOIN categories ON categories.id = posts.category_id").select(" post.id 作为 id,posts.title 作为标题,posts.created_at 作为 created_at,categories.name 作为 cat_n,users.email 作为 user_em").paginate(:page => params[:page]).order("created_at DESC ")
    【解决方案4】:

    你可以在作用域上调用数组方法:

    Post.includes(:user).map { |p| [p.title, p.user.name] }
    

    将获取包含用户的帖子并将每个帖子映射到帖子标题和用户名的元组。

    这可能无法完全回答您的问题,因为我认为您可能希望将查询结果限制在必填字段中,在这种情况下,我认为您可以将 .select('title', 'users.name') 添加到询问。 (暂时无法测试)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多