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

发布于 2024-10-07 05:04:29 字数 851 浏览 4 评论 0原文

我有一个重复的代码块,它在一堆不同的控制器方法中初始化一些变量。有没有办法让我使用模型方法进行 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

I've got a repeated code block that initializes a few variables in a bunch of different controller methods. Is there a way for me to make this DRY with a model method as opposed to repeating the same code block in each controller method?

Basically, it's for a social site, and it's pulling up a user's list of friends, and then building buckets of friends based on the permissions the user has which are stored in a friendship model. This repeated initialization of buckets is what I'm trying to make DRY.

Normally I would use a model method, but in this case, 3 separate variables are being initialized based on one database pull, and this is called often enough I don't want to make it unnecessarily inefficient by hitting the database 3 times. In C, I would just use pointers passed in as variables.

It goes something like this:

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

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

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

发布评论

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

评论(3

清眉祭 2024-10-14 05:04:29

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

  1. 它对于用户及其关系非常具体,最重要的是,它们如何存储在数据库中以及如何从数据库中检索。
  2. 您只需编写一次代码:在用户模型中。

依赖于 Rails 内部查询缓存的快速而简单的方法如下所示。添加到用户模型中:

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

(etc.)

然后您的控制器只需执行以下操作:(

@viewers = @user.view_permission_friends
(etc.)

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

I thought about it for a bit, and I think this code should go into your User model. (Or whatever class @user is in your example above.) Two reasons:

  1. It's very specific to the User, its relationships, and most importantly, how they're stored in and retrieved from the database.
  2. You only need to write the code once: in the User model.

The quick and easy way which relies on Rails' internal query caching would look like this. Added into the User model:

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

(etc.)

Your controllers then simply do this:

@viewers = @user.view_permission_friends
(etc.)

(Note - there's more room for optimization and better flexibility here via lazy caching and parameterizing the permission.)

Saygoodbye 2024-10-14 05:04:29

怎么样...

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

这给你一个带有键的散列而不是单独的数组,但应该足够了。

How about...

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

This gives you a hash with keys instead of individual arrays, but should suffice.

几度春秋 2024-10-14 05:04:29

使用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

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