包括vs连接Activerecord查询示例。还有重构。我做错了什么?

包括vs连接Activerecord查询示例。还有重构。我做错了什么?,activerecord,Activerecord,当前我的控制器如下所示: def index if params[:activity] @trips = Trip.joins(:categories).where("categories.slug = ?", params[:activity]) elsif params[:location] @trips = Trip.joins(:categories).where("categories.slug = ?", params[:location])

当前我的控制器如下所示:

def index
    if params[:activity]
      @trips = Trip.joins(:categories).where("categories.slug = ?", params[:activity])
    elsif params[:location]
      @trips = Trip.joins(:categories).where("categories.slug = ?", params[:location])
    else
      @trips = Trip.includes(:categories).all
    end
end
因为我需要即时加载,而且我在索引视图中进行了大量trip.categories调用,所以我希望使用includes。但我认为我的语法是错误的

def index
    if params[:activity]
      @trips = Trip.includes(:categories).where("categories.slug = ?", params[:activity])
    elsif params[:location]
      @trips = Trip.includes(:categories).where("categories.slug = ?", params[:location])
    else
      @trips = Trip.includes(:categories).all
    end
end
这似乎在视图中抛出了一个错误:

ActionView::Template::Error (PG::UndefinedTable: ERROR:  missing FROM-clause entry for table "categories"
LINE 1: SELECT "trips".* FROM "trips" WHERE (categories.slug = 'hiki...
                                             ^
: SELECT "trips".* FROM "trips" WHERE (categories.slug = 'hiking')):
    12:     </tr>
    13:   </thead>
    14:   <tbody>
    15:     <% @trips.each do |trip| %>
    16:       <tr>
    17:         <td><%= trip.upvotes%></td>
    18:         <td><%= link_to "#{trip.title}", trip_path(trip.id) %></td>
  app/views/trips/index.html.erb:15:in `_app_views_trips_index_html_erb__1143926925325362083_70272895749760'

有人知道问题出在哪里吗?

我认为应该同时使用include和join。联接以限制结果,包括以避免N+1查询。我的建议是这样的

def index
  @trips = Trip.includes(:categories).all
  slug = params[:activity] || params[:location]
  @trips = @trips.joins(:categories).where(categories: { slug: slug }) if slug
end
这样做的好处是,如果您想在以后添加额外的搜索条件,只需在底部添加一行新的广告就很容易了

如果您想在任何其他地方使用此功能,您可能需要考虑将其放入ToIP模型中。

包括默认情况下,不使用连接。Active Record用于尝试和分析您的条件,以查看您是否正在执行任何需要使用include的joins版本的操作,但该操作非常脆弱且容易出错,因此被弃用并最终删除

相反,您必须使用references方法告诉活动记录,例如

Trip.includes(:categories).references(:categories).where("categories.slug =?", params[:location])
您还可以使用eager_load而不是includes显式请求基于联接的策略