Rails获取上一个和下一个活动记录对象的最佳方式
我需要使用Rails获取上一个和下一个活动记录对象。 我做到了,但不知道这是否是正确的方法。
我得到了什么:
控制器:
@product = Product.friendly.find(params[:id]) order_list = Product.select(:id).all.map(&:id) current_position = order_list.index(@product.id) @previous_product = @collection.products.find(order_list[current_position - 1]) if order_list[current_position - 1] @next_product = @collection.products.find(order_list[current_position + 1]) if order_list[current_position + 1] @previous_product ||= Product.last @next_product ||= Product.first
product_model.rb
default_scope -> {order(:product_sub_group_id => :asc, :id => :asc)}
所以,这里的问题是我需要进入我的数据库并获取所有这些ID以了解谁是前一个和下一个。
尝试使用gem order_query ,但它对我不起作用,我注意到它进入数据库并按顺序获取所有记录,所以,这就是为什么我做了同样但只得到id。
我找到的所有解决方案都是简单的订单查询。 按ID排序或类似优先级字段。
没有简单易用的解决方案。
有点脏,但工作方式是仔细挑选出找到下一个和上一个项目的条件。 使用id
它很容易,因为所有的id
都不同, Rails Guy的答案只是描述: next
一个已知的id
选择具有更大id
的第一个条目(如果结果按id
排序,按默认值)。 更重要的是 – 他的答案提示将next
和previous
放入模型类。 这样做。
如果有多个订单标准 ,事情会变得复杂 。 比方说,我们有一组行首先按group
参数排序(可能在不同的行上有相同的值)然后按id
(其中id保持不同,保证)。 结果按group
排序,然后按id
(两个升序 )排序,因此我们可能会遇到两种获取下一个元素的情况,它是列表中第一个有元素的情况,那么(那么多):
- 拥有相同的
group
和更大的id
- 有一个更大的
group
与上一个元素相同:您需要列表中的最后一个元素
- 拥有相同的
group
和较小的id
- 有一个较小的
group
那些分别获取所有下一个和前一个条目。 如果您只需要一个,请使用Rails的first
和last
(由Rails Guy建议)或limit(1)
(并警惕asc / desc排序)。
在Product
型号中写下这些方法:
class Product def next self.class.where("id > ?", id).first end def previous self.class.where("id < ?", id).last end end
现在你可以在你的控制器中做:
@product = Product.friendly.find(params[:id]) @previous_product = @product.next @next_product = @product.previous
请试一试,但未经测试。 谢谢
我认为只用两个SQL请求就可以更快,只选择两行(而不是整个表)。 考虑到您的默认订单按ID排序(否则,强制按ID排序):
@previous_product = Product.where('id < ?', params[:id]).last @next_product = Product.where('id > ?', params[:id]).first
如果产品是最后一个,则@next_product将为nil,如果是第一个,则@previous_product将为nil。
这就是order_query的作用。 请尝试最新版本,如果它不适合您,我可以提供帮助:
class Product < ActiveRecord::Base order_query :my_order, [:product_sub_group_id, :asc], [:id, :asc] default_scope -> { my_order } end @product.my_order(@collection.products).next @collection.products.my_order_at(@product).next
这会运行一个只加载下一条记录的查询。 阅读更多关于Github的信息 。
- ActiveRecord :: EagerLoadPolymorphicError:无法急切加载多态关联
- 重用named_scope来定义另一个named_scope
- 按JSON数组中的匹配数查询和排序
- validationhas_and_belongs_to_many中的至少一个
- 如何对活动供稿中的类似商品进行分组
- 如何从ActiveRecord中的事务中排除模型?
- 在Rails 5.0.0.beta3,-api选项中使用accepts_nested_attributes_for时出现问题
- Rails 3 ActiveRecord交易
- rails 3 / postgres – 如果不应用,则为字符串多长时间:模式中的限制