当使用 update_attributes 更新资源时,acts_as_list 是否应该自动重新排序项目?

发布于 2024-12-10 04:48:33 字数 247 浏览 0 评论 0原文

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

我已经寻求澄清,但有关此插件的文档确实很有限。

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

谢谢

I'm using the acts_as_list plugin with rails 3.1 and whenever I add or remove a resource existing positions are ordered and updated fine. However, when updating the position of a resource with update_attributes no reordering seems to take place and I can be left with resources that have duplicated positions. Is this the correct behaviour of acts_as_list?

I've searched for clarification but documentation on this plug in is really limited.

I'm not using javascript at this stage, the position is simply determined with a select box that has an appropriately limited range.

Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

迷路的信 2024-12-17 04:48:33

当对象更新时,插件中没有任何内容被调用。您必须使用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,但概念就在那里)。这是订购论坛的示例:

forum.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

view

<% 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] %>

也许不是最好的方式,但这是我能想到的最好的方式跟上。如果您计划经常更新位置,或者放置大量对象,那么它可能会太昂贵......但它适用于论坛等小型集合。

There's nothing in the plugin that gets called when the object is updated. You'll have to do it manually using the built-in methods that acts_as_list provides.

The ruby file for this plugin is only 300 lines and easy to follow, it will tell you everything there is to know about acts_as_list... honestly there's not much to it: https://github.com/swanandp/acts_as_list/blob/master/lib/acts_as_list/active_record/acts/list.rb

To do it manually, just get all items with a position higher than the current item and increment each one. This is how I handle it in my apps (not using acts_as_list but the concept is there). This is example is for ordering forums:

forum.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

view

<% 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] %>

Maybe not the best way to do it, but it was the best I could come up with. It will probably be too expensive if you plan on the positions being updated often, or if there will be a lot of objects being positioned... but it works for small collections like forums.

再浓的妆也掩不了殇 2024-12-17 04:48:33

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

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

这显然效率很低,因为每当照片集合被清除时,照片就会被清除并重新创建。设置,但它的优点是可以同时使用 update_attributes(:photos=>[,])update_attributes(:photo_ids=>[123, 456]) (至少在 Rails 2.3.18 中)。

I handled this by overriding the writer for the has_many attribute to clear the list first eg in this case where Photo acts_as_list, I overrode the writer in the referring class:

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

This is obviously quite inefficient because the photos are cleared and recreated whenever the photos collection is set, but it has the advantage of working with both update_attributes(:photos=>[<Photo 1>, <Photo 2>]) or update_attributes(:photo_ids=>[123, 456]) (at least in rails 2.3.18).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文