能否覆盖Rails的路径辅助方法?

10

当前详细的Rails路径帮助程序

我经常编写代码以获取类似以下URL:

link_to @applicant.name, company_job_applicant_path(@company, @job, @applicant)

然而,这段代码更像是这样(冗余的):
link_to @applicant.name, company_job_applicant_path(@applicant.job.company, @applicant.job, @applicant)

这很愚蠢。

需要'pert'路径辅助工具

其他参数可以明显地从@job中派生出来。我真正需要输入的只是:

link_to @applicant.name, applicant_quick_path @applicant

这里有一个定义:

def applicant_quick_path applicant
    company_job_applicant_path(applicant.job.company, applicant.job, applicant)
end

我的问题

  1. 这是一个合理的Rails方式吗?
  2. 我应该把这个方法存储在哪里?
  3. 我目前可以使用app.company_path在控制台中访问这些帮助程序。我应该如何从控制台访问我的新辅助方法?

被标记为重复的问题确实相似,但这个问题是独立的,因为它的答案具有特定的“link_to”视图助手,并且另一个问题是关于路由和路径的,渲染所建议解决方案的细节不同,影响了搜索能力。 - Peter DeWeese
2个回答

7

是的,DRY原则是Rails框架推崇的编程方式。如果您需要重复使用这种方法,最好创建一个视图助手。与其修改路径助手,我会简单地包装Rails的link_to方法。

您可以像这样快速简单地完成:

# app/helpers/application_helper.rb
def link_to_applicant(applicant)
  link_to applicant.name, company_job_applicant_path(applicant.job.company, applicant.job, applicant)
end

# link_to(@applicant)
#=> <a href="/companies/jobs/applicants/123">Peter Nixey</a>

或者,你可以为link_to方法提供额外的支持。

def link_to_applicant(applicant, html_options={})
  link_to applicant.name, company_job_applicant_path(applicant.job.company, applicant.job, applicant), html_options
end

# link_to_applicant(@applicant, :id=>"applicant-#{@applicant.id}")
#=> <a id="applicant-123" href="companies/jobs/applicants/123">Peter Nixey</a>

如果您想完全支持link_to提供的所有功能,可以在此处查看它们允许的多个函数签名。

# rails link_to source code
def link_to(*args, &block)
  if block_given?
    options      = args.first || {}
    html_options = args.second
    link_to(capture(&block), options, html_options)
  else
    name         = args[0]
    options      = args[1] || {}
    html_options = args[2]

    html_options = convert_options_to_data_attributes(options, html_options)
    url = url_for(options)

    href = html_options['href']
    tag_options = tag_options(html_options)

    href_attr = "href=\"#{html_escape(url)}\"" unless href
    "<a #{href_attr}#{tag_options}>#{html_escape(name || url)}</a>".html_safe
  end
end

RSpec笔记

如果你想在RSpec中为你的视图辅助函数编写测试,请遵循以下指南: https://www.relishapp.com/rspec/rspec-rails/docs/helper-specs/helper-spec


我实际上需要出于更复杂的原因这样做(请参见http://stackoverflow.com/questions/8424682/is-it-possible-to-dynamically-remove-a-level-of-rails-resource-nesting)。您的答案非常有帮助,但是在考虑它时,我想知道如何在rspec测试中随后访问那些helpers,例如在测试时,`response.should redirect_to company_path(@company)`?我不能使用原始的长helper,因为我的helpers中实际上会存储逻辑... - Peter Nixey
1
我更新了答案并附加了一些RSpec的注释。 - maček
嗨Macek,感谢您提供的测试助手参考。不过我想知道的是如何在其他方法中访问它们,例如something.should redirect_to my_helper_method(@company) - 谢谢! - Peter Nixey
2
请注意,这种方法(在助手中)无法在控制器中使用。 如果您想要这样做,您需要将该方法移动到应用控制器并通过 helper_method:link_to_applicant 声明为助手。 然后它将在控制器和视图中都可用。 - Dalibor Filus

1

你正在描述一个非常典型的Rails帮助程序。

它们位于app/helpers目录下。

默认情况下,该目录将具有一个ApplicationHelper模块,或者您可以添加自己的模块以便更好地组织它们。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接