Ruby on Rails:干掉重复的代码块,初始化一些变量

时间:2010-12-09 00:59:22

标签: ruby-on-rails dry

我有一个重复的代码块,可以在一堆不同的控制器方法中初始化一些变量。有没有办法让我用模型方法制作这个DRY,而不是在每个控制器方法中重复相同的代码块?

基本上,它是针对社交网站,它正在提取用户的朋友列表,然后根据用户拥有的存储在友谊模型中的权限来构建朋友桶。这个桶的重复初始化就是我想要做的事情。

通常我会使用模型方法,但在这种情况下,基于一个数据库拉动初始化3个单独的变量,这经常被调用,我不想通过点击数据库3次使其不必要地低效。在C中,我只使用作为变量传入的指针。

它是这样的:

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

3 个答案:

答案 0 :(得分:1)

我想了一下,我认为这段代码应该进入你的用户模型。 (或者上面的例子中有@user类。)有两个原因:

  1. 它非常特定于用户及其关系,最重要的是,它们如何存储在数据库中并从数据库中检索。
  2. 您只需编写一次代码:在用户模型中。
  3. 依赖于Rails内部查询缓存的快捷方式看起来像这样。添加到用户模型中:

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

    您的控制器只需执行此操作:

    @viewers = @user.view_permission_friends
    (etc.)
    

    (注意 - 通过延迟缓存和参数化权限,这里有更多的优化空间和更大的灵活性。)

答案 1 :(得分:0)

怎么样......

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

这为您提供了一个带键而不是单个数组的哈希,但应该足够了。

答案 2 :(得分:0)

使用Enumerable#injectEnumerable#find_allObject#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