【问题标题】:rails query only if nested resource exists仅当嵌套资源存在时才查询
【发布时间】:2015-12-06 00:54:08
【问题描述】:

我有一个 Rails 应用程序。我只想在配置文件存在时显示用户(用户 has_one 配置文件)。据我所知,由于我的 index.html.erb 中有一组,我不能简单地使用 ,所以我想在控制器中过滤它。

我应该如何更改查询以仅从数据库中获取具有个人资料的用户?

一般来说,检查嵌套资源是否存在的最佳方法是什么?在带有查询的控制器中执行此操作还是仅在视图中执行此操作?

users/controller.rb

def index
    @q_users = User.ransack(params[:q])
    @users = @q_users.result(distinct: true).includes(:profile).paginate(page: params[:page], per_page: 12)
end

index.html.erb

<div class="user-profile-index" style="padding-right:20px;padding-left:20px;">
  <% @users.each_slice(3) do |users_for_row| %>
    <div class="row">
      <%= render :partial => "user", :collection => users_for_row, as: :user %>
    </div>
  <% end %>
</div>

_user.html.erb

<div class="col-md-4">
  <%= link_to user do %>
    <div class="panel panel-info">
      <div class="panel-heading">
      </div>
      <div class="panel-body">
        <% if user.profile %>
        <% if user.profile.avatar %>
          <%= image_tag user.profile.avatar.url(:base_thumb), class: "avatar" %>
        <% end %>
        <h4><%= user.profile.first_name %> <%= user.profile.last_name %></h4>
        <h5><%= user.profile.company %></h5>
        <% end %>
        <h5><%= user.email %></h5>
      </div>
    </div>
  <% end %>
</div>

用户.rb

has_one :profile, dependent: :destroy

profile.rb

belongs_to :user

【问题讨论】:

  • profileuser 上的字段还是单独的模型?能出示一下相关型号代码吗?
  • Patrick,已添加模型

标签: ruby-on-rails postgresql activerecord controller


【解决方案1】:

includes(:profile) 替换为:

joins(:profile).preload(:profile)

joins 将为您提供 INNER JOIN,它将仅选择具有配置文件的用户。 preload 将预加载在 joins 中找到的配置文件(以避免 N+1 问题)。 您还可以将此连接移动到用户模型中的单独范围中,例如with_profile.

【讨论】:

  • 我相信这里不需要where,因为条件会从对join的调用中生成。 joins(:profile).preload(:profile) 应该可以工作。
猜你喜欢
  • 2020-06-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多