是否有一种DRY方法可以使用相同的参数调用不同的Ruby方法?

时间:2013-02-28 12:59:04

标签: ruby-on-rails ruby

我有这样的代码。

if star
  href = star_path( :"star[model]" => model.class, :"star[model_id]" => model.id ))
else
  href = unstar_path( :"star[model]" => model.class, :"star[model_id]" => model.id ))
end

正如您所看到的,它调用的是star_path或unstar_path帮助程序,但具有相同的参数。我很难重复这样的参数,感觉应该有更好的方法。

谢谢!

7 个答案:

答案 0 :(得分:6)

options = { :"star[model]" => model.class, :"star[model_id]" => model.id }

if star
  href = star_path(options)
else
  href = unstar_path(options)
end

答案 1 :(得分:3)

两种方式:

  • 首先分配给变量

    path_options = :"star[model]" => model.class, :"star[model_id]" => model.id
    href = star ? star_path( path_options ) : unstar_path( path_options )
    
  • 使用自定义助手

    def custom_star_path( options = {} )
      action = options.delete( :action ) || :star
      action == :star ? star_path( options ) : unstar_path( options )
    end
    

    并致电:

    custom_star_path( :action => (:unstar unless star), :"star[model]" => model.class, :"star[model_id]" => model.id )
    

    甚至更简单:

    def custom_star_path( options = {} )
      options.delete( :has_star ) ? star_path( options ) : unstar_path( options )
    end
    
    custom_star_path( :has_star => star, :"star[model]" => model.class, :"star[model_id]" => model.id )   
    

答案 2 :(得分:2)

href =
send(
  star ? :star_path : :unstar_path,
  "star[model]".to_sym => model.class, "star[model_id]".to_sym => model.id
)

答案 3 :(得分:2)

toggle_star_path助手

怎么样?
def toggle_star_path star, model
  options = { :"star[model]" => model.class, :"star[model_id]" => model.id }
  star ? unstar_path(options) : star_path(options)
end

然后在您的视图中,您只需致电:

toggle_star_path star, model

答案 4 :(得分:1)

如果你想使用变量方法,那么我认为send是可行的方法。

根据document

 send(symbol [, args...]) → obj
 send(string [, args...]) → obj
  

调用symbol / string标识的方法,并将指定的参数传递给它。如果名称发送与obj中的现有方法发生冲突,则可以使用__send__。当方法由字符串标识时,字符串将转换为符号。

答案 5 :(得分:1)

尝试如下,简单的2行

options = { :"star[model]" => model.class, :"star[model_id]" => model.id }

href = star ? star_path(options) : unstar_path(options)

答案 6 :(得分:0)

使用此处发布的其他解决方案,我解决了这个问题:

options = {:"star[model]" => model.class, :"star[model_id]" => model.id}
href = send((star ? :unstar_path : :star_path ), options)