是否可以覆盖Rails路径助手方法?

Pet*_*xey 10 routing ruby-on-rails

当前详细的rails路径助手

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

link_to @applicant.name, company_job_applicant_path(@company, @job, @applicant)
Run Code Online (Sandbox Code Playgroud)

但是这段代码看起来更像是这个(冗余)片段:

link_to @applicant.name, company_job_applicant_path(@applicant.job.company, @applicant.job, @applicant)
Run Code Online (Sandbox Code Playgroud)

这太傻了.

必需的'pert'路径助手

其他参数可以清楚地从@job中导出.我真正需要输入的是:

link_to @applicant.name, applicant_quick_path @applicant
Run Code Online (Sandbox Code Playgroud)

哪里有一个定义:

def applicant_quick_path applicant
    company_job_applicant_path(applicant.job.company, applicant.job, applicant)
end
Run Code Online (Sandbox Code Playgroud)

我的问题

  1. 这样Rails Way做是否合理
  2. 我应该在哪里存储这种方法?
  3. 我现在可以使用控制台访问这些助手app.company_path.我如何从控制台访问我的新助手方法?

mač*_*ček 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>
Run Code Online (Sandbox Code Playgroud)

或者,您可以为该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>
Run Code Online (Sandbox Code Playgroud)

如果要完全支持所提供的所有功能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
Run Code Online (Sandbox Code Playgroud)

RSpec注意到

如果您想编写测试在RSpec的视图助手,按照本指南: https://www.relishapp.com/rspec/rspec-rails/docs/helper-specs/helper-spec

  • 另请注意,这种方式(在帮助程序中)您将无法在控制器中使用它.如果你想要这个,你必须将该方法移动到应用程序控制器并通过`helper_method:link_to_applicant`将其声明为帮助器.然后它将在控制器和视图中可用. (2认同)