我有以下ActiveRecord模型
class Publication < ActiveRecord::Base
attr_accessible :id, :pname
has_many :advertisements
end
class Vendor < ActiveRecord::Base
attr_accessible :id, :vname
has_many :advertisements
end
class Advertisement < ActiveRecord::Base
attr_accessible :id, :vendor_id, :publication_id, :prose, :aname
belongs_to :vendor
belongs_to :publication
end
这些表格与其可访问属性具有相同的字段。
我希望能够对发布名称,广告名称或供应商名称进行排序,升序或降序。
我还有广告控制器,我想在其中显示广告列表。该列表显示广告的名称(aname),广告的散文(散文),供应商的名称(vname)以及出版物的名称(pname)。
按发布名称排序的SQL查询类似于:
SELECT ads.aname AS aname, ads.id, ads.prose, ven.vname AS vname, pub.pname AS pname
FROM advertisements AS ads
INNER JOIN publications AS pub ON ads.publication_id = pub.id
INNER JOIN vendors AS ven ON ads.vendor_id = ven.id
ORDER BY <sort_column> <sort_order>
其中sort_column可以是&#34; pname&#34;,&#34; aname&#34;或&#34; vname&#34;和sort_order可以是&#34; ASC&#34之一;或者&#34; DESC&#34;,两者都将作为Web表单中的参数以及分页页码。
控制器索引代码与 类似 :
class AdvertisementsController < ApplicationController
def index
sort_column = params[:sort_column]
sort_order = params[:sort_order]
@ads = Advertisement.join( somehow join tables)
.where(some condition).where(some other condition)
.order("#{sort_column} #{sort_order}") ### I don't know what to do here
.paginate(page: params[:page], per_page: 10) #from will_paginate
end
# other controller methods.......
end
索引视图表片段(用SLIM编写)如下所示:
tr
- @ads.each do |ad|
td = ad.id
td = ad.aname
td = ad.pname
td = ad.vname
我知道我可以使用AREL来做到这一点,但是我一直在使用AREL在Rails控制台中试图用分页生成和执行这个查询,并在网上阅读教程我不能弄清楚如何在AREL中获取此查询,对连接字段进行排序,并能够使用will_paginate Ruby查询子句对查询进行分页。
如何使用AREL,甚至ActiveRecord来执行此操作?我感谢任何帮助。
答案 0 :(得分:2)
您可以使用vanilla ActiveRecord方法完成您想要的任务,而不使用Arel。你所拥有的非常接近,这可能会帮助你实现目标。
# whitelist incoming params
sort_column = %w(pname aname vname).include?(params[:sort_column]) ? params[:sort_column] : "pname"
sort_order = %w(asc desc).include?(params[:sort_order]) ? params[:sort_order] : "desc"
@ads = Advertisement.select("advertisements.*, vendors.vname, publications.pname").
joins(:publication, :vendor).
where(some condition).
where(some other condition).
order("#{sort_column} #{sort_order}").
page(params[:page]).per_page(10)
答案 1 :(得分:0)
您可以让解决方案同时适用于Arel和ActiveRecord。我建议你尽可能多地坚持使用ActiveRecord,除非你不能用AR做到这一点。
Arel非常棒,但最近我发现在我的代码库中,它会降低整体可读性,特别是如果你将它与AR混合使用或者使用过多的话。
还有其他一些建议:
关于尝试使用&#34的相同查询;包括&#34;而不是使用&#34;加入&#34;。您可能比必须添加select子句更容易。我使用include for outerjoins,但是为了更详细的比较,google&#34;包括vs join&#34;,它非常有趣。
在我的第一个建议完全相反的方向上,如果您的查询变得复杂,我强烈建议您使用https://github.com/activerecord-hackery/ransack或https://github.com/activerecord-hackery/squeel作为您的用例。 特别是如果你没有为了学习目的而做上述事情。