如何更改resource_url中的资源,具体取决于调用它的模型?

时间:2015-08-21 21:27:04

标签: ruby-on-rails ruby

我有以下代码:

  def perform(message, slug)
    url = Bitly.client.shorten(post_url(slug)).short_url
    tweet("#{message} #{url}")
  end

假设我还有一个 Book 模型(上面的代码适用于Post模型)。如果我想获得一本书的网址,我会使用以下帮助book_url(slug)

如何根据调用表演的模型将post_url更改为book_url?

所以,如果从Book模型调用该方法,我有book_path,如果来自Post模型,我有post_path。

2 个答案:

答案 0 :(得分:1)

您可以使用send()方法动态调用这些帮助程序或模式函数。该方法来自Ruby,这里有更多信息。 http://apidock.com/ruby/Object/send

在你的情况下你就是这样做的:

model_name = object.class.to_s.underscore
send("#{model_name}_path", slug)

修改 至于你的代码可能是

send("#{model_name}_url", slug, host: ActionMailer::Base.default_url_options[:host] )

我在我的控制台中为你试了一下:

include Rails.application.routes.url_helpers
model_name = User.first.class.to_s.underscore
=> "user"
send("#{model_name}_path", User.first.cached_slug)
=> "/community/user/hummel"
send("#{model_name}_path", User.first.id)
=> "/community/user/1"

按要求

由于您要将主机发送到该方法,请使用_url代替_path帮助程序,并将额外的参数host添加到方法中。

send("#{model_name}_url", User.first.cached_slug, host: "google.com")
=>http://google.com/community/user/hummel

答案 1 :(得分:1)

如果您使用Rails标准路由,例如:resources :books 你可以做到以下几点:

def perform(message, resource)
  url = Bitly.client.shorten(url_for(resource)).short_url
  tweet("#{message} #{url}")
end

有关详情,请参阅url_for