2010-08-29 3 views
0

Je rencontre un problème lors de l'écriture d'une action de contrôleur qui prend les identifiants de message transmis en tant que paramètre et les trie dans un ordre spécifique avant de les publier.Tri des éléments dans Rails Contrôleur Méthode

Les messages ont un attribut position (j'utilise acts_as_list pour le tri) et sont publiés ou non publiés (consultable avec les named_scopes Post.published et Post.unpublished, en conséquence).

Essentiellement, il y a une interface JavaScript qui permet aux utilisateurs de faire glisser les messages non publiés dans une file d'attente, et les publier en passant les ids comme paramètre post_ids à une méthode du contrôleur qui ressemble à ceci:

def publish 
    Post.update_all(['published=?', true], :id => params[:post_ids]) 
    redirect_to admin_path 
end 

Publishing les messages comme celui-ci fonctionne bien. Ce que je dois faire ensuite est de trier les postes par leur position dans un ordre spécifique, et c'est là que j'ai des problèmes. Supposons qu'un utilisateur traîne 5, puis 3, puis 7 dans la file d'attente et clique sur "Publier". Ce que je veux faire est alors organiser tous les postes pour avoir 5, 3, 7 aux premières positions dans l'ordre, et ensuite le reste des objets Post dans l'ordre où ils étaient déjà, donc le tri par Post.position serait [5, 3, 7, ...the rest of the posts in order here...]

Ensuite, si l'utilisateur de faire glisser deux nouveaux messages dans la file d'attente, puis cliquez sur « Publier » (cette fois, disons messages 2 et 4), les postes devraient être dans l'ordre [2, 4, 5, 3, 7, ...the rest of the posts in order here...]

Ensuite, pour un dernier exemple, disons que l'utilisateur déplace les postes 10, 1 et 12 sur la file d'attente et publie, l'ordre doit être [10, 1, 12, 2, 4, 5, 3, 7, ...the rest of the posts in order here...] etc ...

Je montrerais le code sur lequel je travaillais, mais je ne suis pas sûr que ce serait utile car je ne l'ai pas eu à trier correctement. Mais essentiellement j'imagine que c'est une question de prendre deux tableaux, le premier étant tous les postes et le second étant les postes à publier, et mettre chaque élément dans le tableau Posts to publish au début du tableau All Posts, puis publier. Je n'arrive juste pas à le faire fonctionner. Toute aide ici serait grandement appréciée, et je vous remercie d'avance pour votre temps!

Éditer Si cela vous aide, voici le code que j'ai écrit jusqu'à maintenant. Lors du test, il semble que cette méthode trie correctement les messages de la file d'attente la première fois, mais les publications suivantes ne sont pas placées au premier plan de la liste Posts publiée.

def publish 
    if params[:to_publish].present? 
    # :to_publish are the posts dragged into the queue in order. 
    # Here I'm cleaning up the Javascript input and then iterating 
    # through them to update their sort order. 
    params[:to_publish].to_s.split(",").uniq!.each_with_index do |id, index| 
     Post.update_all(['position=?', index + 1], ['id=?', id]) 
    end 
    end 
    # :post_ids are the posts to be published, order is irrelevant. 
    # For client-side reasons they're passed as a separate parameter. 
    Post.update_all(['published=?', true], :id => params[:post_ids]) 
    redirect_to admin_path 
end 

Répondre

0

params [: à_publier] .to_s.split (","). Uniq!

Ici, pourquoi faites-vous une vérification unique? Est-ce une mesure défensive?

Notez également que uniq! renvoie zéro si aucun doublon n'est trouvé, ce qui amène votre code à renvoyer une erreur de référence nulle si le tableau n'a pas de doublons.

Si vous avez un bloc de secours dans votre code qui avale cette erreur de référence nulle, vous êtes en difficulté!

+0

Oui, merci. Cette scission hacky et uniq! line est juste une solution de contournement rapide en raison de JavaScript peu sophistiqué existant actuellement sur le côté client. Lorsque je nettoierai le code JavaScript, je n'aurai pas besoin d'appeler uniq !, mais c'est une priorité moins importante pour moi maintenant. Merci encore pour ce conseil. – btw

Questions connexes