[英]Ruby on Rails: DRYing a repeated code block that initializes a few variables
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?
有没有一种方法可以使我使用模型方法进行DRY,而不是在每个控制器方法中重复相同的代码块?
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. 通常,我会使用模型方法,但是在这种情况下,将基于一个数据库请求初始化3个单独的变量,这被称为足够多了,我不想通过打3次数据库来使其不必要地效率低下。 In C, I would just use pointers passed in as variables.
在C语言中,我只会使用传入的指针作为变量。
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
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:
(或上面的示例中的@user类。)两个原因:
The quick and easy way which relies on Rails' internal query caching would look like this. 依赖Rails内部查询缓存的快速简便的方法如下所示。 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.) (请注意-通过惰性缓存和参数化权限,这里有更多的优化空间和更好的灵活性。)
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. 这为您提供了一个带有键而不是单个数组的散列,但足够了。
Use Enumerable#inject
, Enumerable#find_all
and Object#instance_variable_set
: 使用
Enumerable#inject
, Enumerable#find_all
和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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.