3

J'utilise le plugin acts_as_list avec les rails 3.1 et chaque fois que j'ajoute ou supprime une ressource, les positions existantes sont commandées et mises à jour correctement. Cependant, lors de la mise à jour de la position d'une ressource avec update_attributes, aucune réorganisation ne semble avoir lieu et je peux me retrouver avec des ressources qui ont des positions dupliquées. Est-ce le bon comportement de acts_as_list?Est-ce que acts_as_list doit réorganiser automatiquement les éléments lorsqu'une ressource est mise à jour avec update_attributes?

J'ai cherché des explications mais la documentation sur ce plug-in est vraiment limitée.

Je n'utilise pas javascript à ce stade, la position est simplement déterminée avec une boîte de sélection qui a une plage limitée appropriée.

Merci

Répondre

2

Il n'y a rien dans le plug-in qui est appelée lorsque l'objet est mis à jour. Vous devrez le faire manuellement en utilisant les méthodes intégrées que acts_as_list fournit.

Le fichier rubis pour ce plug-in est à seulement 300 lignes et facile à suivre, il vous dira tout ce qu'il ya à savoir sur acts_as_list ... Honnêtement, il n'y a pas grand-chose à ce: https://github.com/swanandp/acts_as_list/blob/master/lib/acts_as_list/active_record/acts/list.rb

Pour le faire manuellement, Il suffit d'obtenir tous les éléments avec une position plus élevée que l'élément actuel et d'incrémenter chacun d'eux. C'est ainsi que je le gère dans mes applications (sans utiliser acts_as_list mais le concept est là). Ceci est par exemple est pour les forums de commande:

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 

vue

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

Peut-être pas la meilleure façon de le faire, mais il était le meilleur Je pourrais venir avec. Ce sera probablement trop cher si vous prévoyez souvent de mettre à jour les positions, ou si beaucoup d'objets seront positionnés ... mais cela fonctionne pour les petites collections comme les forums.

0

Je me suis occupé en surchargeant l'auteur de l'attribut has_many pour effacer la première liste, par exemple dans ce cas où acts_as_list photo, je l'emportaient sur l'écrivain dans la classe référence:

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

Ceci est évidemment tout à fait inefficace, car les photos sont effacées et recréées à chaque fois que la collection de photos est définie, mais elle a l'avantage de travailler avec update_attributes(:photos=>[<Photo 1>, <Photo 2>]) ou update_attributes(:photo_ids=>[123, 456]) (au moins sur les rails 2.3.18).

Questions connexes