(@products + @collections + @users + @questions).map do |r|
@results << {
:label => ["Product", "Collection", "User"].include?(r.class.name) ? r.name : r.question,
:category => r.class.name,
:href => eval("#{r.class.name.downcase}_path(r)")
}
end
我目前正在寻找是否有办法不在字符串上使用eval将其转换为帮助器。
注意:此代码目前位于控制器中。 Rails 2.3.11
答案 0 :(得分:1)
您可以尝试这样的事情:
:href => self.send("#{r.class.name.downcase}_path".to_sym, r)
由于我不完全确定这里的背景,所以我不会百分之百地确信这会起作用,但如果这是一个你试图引用的方法,那么自我就是最可能的目标。
答案 1 :(得分:1)
使用benchmarks shown here动态调用方法有3种方法。我总结一下下面的文章:
在ruby中动态调用方法的一种方法是向对象发送消息:
p s.send(:length) #=> 6
p s.send(:include?,"hi") #=> true
第二种方法是实例化方法对象,然后调用它:
method_object = s.method(:length)
p method_object.call #=> 6
method_object = s.method(:include?)
p method_object.call('hi') #=> true
第三种方法是使用eval方法:
eval "s.length" #=> 6
eval "s.include? 'hi'" #=>true
根据基准测试结果,SLOWEST是eval所以我会改用send
。
#######################################
##### The results
#######################################
#Rehearsal ----------------------------------------
#call 0.050000 0.020000 0.070000 ( 0.077915)
#send 0.080000 0.000000 0.080000 ( 0.086071)
#eval 0.360000 0.040000 0.400000 ( 0.405647)
#------------------------------- total: 0.550000sec
# user system total real
#call 0.050000 0.020000 0.070000 ( 0.072041)
#send 0.070000 0.000000 0.070000 ( 0.077674)
#eval 0.370000 0.020000 0.390000 ( 0.399442)
答案 2 :(得分:1)
你应该做的一些事情有所不同,其中一些已被其他答案暗示或明确说明,但我认为这样做的更好:
@results = (@products + @collections + @users + @questions).map do |r|
{
:label => r.try(:question) || r.name,
:category => r.class.model_name.human,
:href => send(:"#{r.class.model_name.underscore}_path", r)
}
end
map
,只需将结果分配给@results
。 to_label
方法,这很简单,但假设问题没有使用try
和二进制文件的名称,或者只是解决问题的简单方法。 / LI>
BedSheet
这样的类时,你会希望它显示为“床单”。不妨开始吧。 bed_sheet_path
,而不是bedsheet_path
。 send
而不是eval
,如其他答案中所述。不需要使用显式to_sym
,因为Ruby支持使用双引号来直接创建符号。 另一个快速说明,我不知道Rails 2.x是否相同,但是在Rails 3中你不需要使用路径助手链接到模型的实例,因为大多数html帮助器方法都会转换自动(例如link_to 'A Product', @product
)。
瞧。
答案 3 :(得分:1)
使用polymorphic_path
@results = (@products + @collections + @users + @questions).map do |r|
{
:label => ["Product", "Collection", "User"].include?(r.class.name) ? r.name : r.question,
:category => r.class.name,
:href => polymorphic_path(r)
}
end
答案 4 :(得分:0)
您可以使用查找表:
class_procs = {
Product => {
:path => lambda { |r| product_path(r) },
:label => lambda { |r| r.name }
},
Collection => {
:path => lambda { |r| collection_path(r) },
:label => lambda { |r| r.name }
}
User => {
:path => lambda { |r| user_path(r) },
:label => lambda { |r| r.name }
},
Question => {
:path => lambda { |r| question_path(r) },
:label => lambda { |r| r.question }
}
}
(@products + @collections + @users + @questions).map do |r|
procs = class_procs[r.class]
@results << {
:label => procs[:label].call(r),
:category => r.class.name,
:href => procs[:path].call(r)
}
end
如果您的需求变得更加复杂,那么您可以轻松地将每类Hashes转换为单独的类,以防止内部Hashes变得过于庞大和复杂。