3

我正在使用带有 rails 3.1 的acts_as_list 插件,每当我添加或删除资源时,现有位置都会被排序和更新。但是,当使用 update_attributes 更新资源的位置时,似乎不会发生重新排序,并且我可能会留下具有重复位置的资源。这是acts_as_list 的正确行为吗?

我已经寻求澄清,但关于这个插件的文档真的很有限。

在这个阶段我没有使用 javascript,位置只是通过一个具有适当限制范围的选择框来确定。

谢谢

4

2 回答 2

2

更新对象时,插件中没有任何内容被调用。您必须使用acts_as_list 提供的内置方法手动完成。

这个插件的 ruby​​ 文件只有 300 行并且易于理解,它会告诉你关于acts_as_list 的所有信息......老实说,它并不多:https ://github.com/swanandp/acts_as_list/blob/ master/lib/acts_as_list/active_record/acts/list.rb

要手动执行此操作,只需获取位置高于当前项目的所有项目并递增每个项目。这就是我在我的应用程序中处理它的方式(不使用acts_as_list,但概念就在那里)。这是订购论坛的示例:

论坛.rb

PositionOptions = [["First Forum", "-1"]] + all.map{|forum| ["After #{forum.subject}", forum.position]}

attr_accessor :position_before
  before_save :set_position, :if => "position_before.present?"
    def set_position
      self.position = position_before.to_i + 1
    end

  after_save :do_positions, :if => "position_before.present?"
    def do_positions
      Forum.where('position >= ? AND id != ?', position, id).order('position, updated_at DESC').all.each_with_index do |forum, index|
        forum.update_attribute('position', position + index + 1)
      end
    end

看法

<% position_options = Forum::PositionOptions %>
<%= f.select :position_before, position_options.reject {|forum| @forum.position == forum[1]}, :selected => position_options[position_options.index {|p| p[1] == @forum.position} - 1][1] %>

也许不是最好的方法,但这是我能想到的最好的方法。如果您计划经常更新位置,或者要放置很多对象,这可能会太昂贵......但它适用于论坛等小型收藏。

于 2011-10-14T12:30:39.403 回答
0

我通过覆盖 has_many 属性的 writer 来处理此问题,以首先清除列表,例如在 Photoacts_as_list 的这种情况下,我在引用类中覆盖了 writer:

def photos_with_clear=(photos)
  self.photos_without_clear=[]
  self.photos_without_clear=photos
end
alias_method_chain :photos=, :clear

这显然是非常低效的,因为只要设置了照片集合,就会清除并重新创建照片,但它具有同时使用两者update_attributes(:photos=>[<Photo 1>, <Photo 2>])update_attributes(:photo_ids=>[123, 456])(至少在 rails 2.3.18 中)的优势。

于 2013-05-08T20:19:10.623 回答