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

时间:2022-12-24 17:28:54

I have code like this.

我有这样的代码。

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

As you can see, it's calling either the star_path or the unstar_path helper, but with the same parameters. I feel bad repeating the parameters like this, it feels like there should be a better way.

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

Thanks!

7 个解决方案

#1


2  

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

#2


6  

try

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

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

#3


3  

two ways:

  • assign to a variable first

    首先分配给变量

    path_options = :"star[model]" => model.class, :"star[model_id]" => model.id
    href = star ? star_path( path_options ) : unstar_path( path_options )
    
  • use a custom helper

    使用自定义助手

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

    and call with :

    并致电:

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

    or even simpler:

    甚至更简单:

    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 )   
    

#4


2  

How about a toggle_star_path helper

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

Then in your view you just call:

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

toggle_star_path star, model

#5


1  

If you want to use a variable method, then I think send is way to go.

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

According to the document:

根据该文件:

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

Invokes the method identified by symbol/string, passing it any arguments specified. You can use __send__ if the name send *es with an existing method in obj. When the method is identified by a string, the string is converted to a symbol.

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

#6


1  

try as follow, simple 2 lines

尝试如下,简单2行

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

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

#7


0  

Working with the other solutions posted here, I settled on this:

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

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

#1


2  

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

#2


6  

try

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

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

#3


3  

two ways:

  • assign to a variable first

    首先分配给变量

    path_options = :"star[model]" => model.class, :"star[model_id]" => model.id
    href = star ? star_path( path_options ) : unstar_path( path_options )
    
  • use a custom helper

    使用自定义助手

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

    and call with :

    并致电:

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

    or even simpler:

    甚至更简单:

    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 )   
    

#4


2  

How about a toggle_star_path helper

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

Then in your view you just call:

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

toggle_star_path star, model

#5


1  

If you want to use a variable method, then I think send is way to go.

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

According to the document:

根据该文件:

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

Invokes the method identified by symbol/string, passing it any arguments specified. You can use __send__ if the name send *es with an existing method in obj. When the method is identified by a string, the string is converted to a symbol.

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

#6


1  

try as follow, simple 2 lines

尝试如下,简单2行

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

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

#7


0  

Working with the other solutions posted here, I settled on this:

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

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