2010-12-09 3 views
0

J'ai un bloc de code répété qui initialise quelques variables dans un tas de différentes méthodes de contrôleur. Y a-t-il un moyen pour moi de faire ce DRY avec une méthode modèle plutôt que de répéter le même bloc de code dans chaque méthode de contrôleur? Fondamentalement, c'est pour un site social, et il tire la liste d'amis d'un utilisateur, puis construit des compartiments d'amis en fonction des autorisations dont dispose l'utilisateur et qui sont stockées dans un modèle d'amitié. Cette initialisation répétée des seaux est ce que j'essaie de faire DRY.Ruby on Rails: DRYing un bloc de code répété qui initialise quelques variables

Normalement j'utiliserais une méthode de modèle, mais dans ce cas, 3 variables séparées sont initialisées en fonction d'une extraction de base de données, et ceci est assez souvent appelé, je ne veux pas rendre inutilement inefficace en frappant la base de données. fois. En C, j'utiliserais juste des pointeurs passés en tant que variables.

Il va quelque chose comme ceci:

def example_method 
    friendships = @user.friendships 
    view_permission_friends = [] 
    write_permission_friends = [] 
    message_permission_friends = [] 
    for friendship in friendships 
    if friendship.view_permission then view_permission_friends << friendship.friend_id end 
    if friendship.write_permission then write_permission_friends << friendship.friend_id end 
    if friendship.message_permission then message_permission_friends << friendship.friend_id end 
    end 
    #Do something with the 3 initialized arrays here 
end 

Répondre

1

Je pensais à ce sujet pour un peu, et je pense que ce code devrait aller dans votre modèle d'utilisateur. (Ou quelle que soit la classe @user est dans votre exemple ci-dessus.) Deux raisons:

  1. Il est très spécifique à l'utilisateur, ses relations, et surtout, la façon dont ils sont stockés et récupérés à partir de la base de données.
  2. Il vous suffit d'écrire le code une fois: dans le modèle User.

La méthode rapide et simple qui repose sur la mise en cache interne des requêtes de Rails devrait ressembler à ceci. Ajouté dans le modèle de l'utilisateur:

def view_permission_friends 
    return friendships.select{|f| f.view_permission} 
end 

(etc.) 

Vos contrôleurs puis font tout simplement ceci: (. Remarque - il y a plus de place pour l'optimisation et une meilleure flexibilité ici par la mise en cache paresseux et paramétrer l'autorisation)

@viewers = @user.view_permission_friends 
(etc.) 

0

Que diriez-vous ...

rv = {} 
%w(view write message).each do |type| 
    rv["#{type}_permission_friends"] = @user.friendships.select{|f|f.send(:"#{type}_permission")}.collect(&:friend_id) 
end 

Cela vous donne un hachage avec les touches au lieu de tableaux individuels, mais devrait suffire.

+0

Je pense que je n'ai pas été clair dans ma question, que j'ai révisé. J'essaie d'éliminer l'utilisation répétée de ce bloc entier dans chaque méthode de contrôleur, plutôt que d'optimiser le bloc lui-même. Je suis d'accord avec la division du tableau en lignes séparées. Bien que vous ayez raison, si je devais renvoyer un hachage à partir d'une méthode de modélisation, cela me permettrait de simplement coller les tableaux dans le hachage. Est-ce la meilleure façon de faire cela? –

0

Utilisez Enumerable#inject, Enumerable#find_all et Object#instance_variable_set:

def example_method 
    %w{view write message}.inject({}) do |memo, s| 
    friendships = @user.friendships.find_all{ |f| f.send("#{s}_permission") } 
    memo["#{s}_permission_friends"] = friendships 
    end.each do |key, value| 
    instance_variable_set "@#{key}", value 
    end 

    # now you have 3 arrays: 
    # @view_permission_friends, @write_permission_friends and @message_permission_friends 
end