Action View URL 帮助器
提供一组用于创建链接和获取依赖于路由子系统(参见 ActionDispatch::Routing
)的 URL 的方法。这使您能够在视图和控制器中使用相同的链接格式。
- #
- B
- C
- L
- M
- P
- S
常量
BUTTON_TAG_METHOD_VERBS | = | %w{patch put delete} |
此帮助器可以包含在任何包含路由的 URL 帮助器(routes.url_helpers)的类中。这里提供的一些方法仅在请求的上下文中有效(例如, |
||
STRINGIFIED_COMMON_METHODS | = | { get: "get", delete: "delete", patch: "patch", post: "post", put: "put", }.freeze |
实例公共方法
button_to(name = nil, options = nil, html_options = nil, &block) 链接
生成一个包含单个按钮的表单,该按钮提交到由一组 options
创建的 URL。这是确保不会通过搜索机器人或加速器触发导致数据更改的链接的最安全方法。
您可以使用 html_options
控制表单和按钮的行为。html_options
中的大多数值都会传递给按钮元素。例如,在 html_options
中传递 :class
选项将设置按钮元素的类属性。
可以通过在 html_options
中传递 :form_class
选项来设置表单元素的类属性。默认值为 "button_to"
,允许对表单及其子元素进行样式设置。
表单默认情况下提交 POST 请求。您可以通过 html_options
中的 :method
选项指定不同的 HTTP 动词。
如果从 button_to
生成的 HTML 按钮不适用于您的布局,您可以考虑使用 link_to
方法以及 data-turbo-method
属性,如 link_to
文档中所述。
选项
options
哈希接受与 url_for
相同的选项。要生成没有 [action]
属性的 <form>
元素,请传递 false
<%= button_to "New", false %>
# => "<form method="post" class="button_to">
# <button type="submit">New</button>
# <input name="authenticity_token" type="hidden" value="10f2163b45388899ad4d5ae948988266befcb6c3d1b2451cf657a0c293d605a6"/>
# </form>"
html_options
中的大多数值都会传递给按钮元素,但有一些特殊选项
-
:method
- HTTP 动词的符号。支持的动词为:post
、:get
、:delete
、:patch
和:put
。默认情况下为:post
。 -
:disabled
- 如果设置为 true,它将生成一个禁用的按钮。 -
:data
- 此选项可用于添加自定义数据属性。 -
:form
- 此哈希将是表单属性 -
:form_class
- 这控制放置提交按钮的表单的类 -
:params
- 要在表单中作为隐藏字段呈现的参数的哈希。
示例
<%= button_to "New", action: "new" %>
# => "<form method="post" action="/controller/new" class="button_to">
# <button type="submit">New</button>
# <input name="authenticity_token" type="hidden" value="10f2163b45388899ad4d5ae948988266befcb6c3d1b2451cf657a0c293d605a6" autocomplete="off"/>
# </form>"
<%= button_to "New", new_article_path %>
# => "<form method="post" action="/articles/new" class="button_to">
# <button type="submit">New</button>
# <input name="authenticity_token" type="hidden" value="10f2163b45388899ad4d5ae948988266befcb6c3d1b2451cf657a0c293d605a6" autocomplete="off"/>
# </form>"
<%= button_to "New", new_article_path, params: { time: Time.now } %>
# => "<form method="post" action="/articles/new" class="button_to">
# <button type="submit">New</button>
# <input name="authenticity_token" type="hidden" value="10f2163b45388899ad4d5ae948988266befcb6c3d1b2451cf657a0c293d605a6"/>
# <input type="hidden" name="time" value="2021-04-08 14:06:09 -0500" autocomplete="off">
# </form>"
<%= button_to [:make_happy, @user] do %>
Make happy <strong><%= @user.name %></strong>
<% end %>
# => "<form method="post" action="/users/1/make_happy" class="button_to">
# <button type="submit">
# Make happy <strong><%= @user.name %></strong>
# </button>
# <input name="authenticity_token" type="hidden" value="10f2163b45388899ad4d5ae948988266befcb6c3d1b2451cf657a0c293d605a6" autocomplete="off"/>
# </form>"
<%= button_to "New", { action: "new" }, form_class: "new-thing" %>
# => "<form method="post" action="/controller/new" class="new-thing">
# <button type="submit">New</button>
# <input name="authenticity_token" type="hidden" value="10f2163b45388899ad4d5ae948988266befcb6c3d1b2451cf657a0c293d605a6" autocomplete="off"/>
# </form>"
<%= button_to "Create", { action: "create" }, form: { "data-type" => "json" } %>
# => "<form method="post" action="/images/create" class="button_to" data-type="json">
# <button type="submit">Create</button>
# <input name="authenticity_token" type="hidden" value="10f2163b45388899ad4d5ae948988266befcb6c3d1b2451cf657a0c293d605a6" autocomplete="off"/>
# </form>"
已弃用:Rails UJS 属性
在 Rails 7 之前,Rails 默认情况下附带了一个名为 @rails/ujs
的 JavaScript 库。在 Rails 7 之后,此库不再默认启用。此库与以下选项集成
-
:remote
- 如果设置为 true,将允许@rails/ujs
控制提交行为。默认情况下,此行为是 Ajax 提交。
@rails/ujs
还与以下 :data
选项集成
-
confirm: "question?"
- 这将允许@rails/ujs
使用指定的问号进行提示(在本例中,结果文本将为question?
)。如果用户接受,则按钮将正常处理,否则不执行任何操作。 -
:disable_with
- 此参数的值将用作提交表单时提交按钮禁用版本的 value。
Rails UJS 示例
<%= button_to "Create", { action: "create" }, remote: true, form: { "data-type" => "json" } %>
# => "<form method="post" action="/images/create" class="button_to" data-remote="true" data-type="json">
# <button type="submit">Create</button>
# <input name="authenticity_token" type="hidden" value="10f2163b45388899ad4d5ae948988266befcb6c3d1b2451cf657a0c293d605a6" autocomplete="off"/>
# </form>"
来源:显示 | 在 GitHub 上
current_page?(options = nil, check_parameters: false, **options_as_kwargs) 链接
如果当前请求 URI 是由给定的 options
生成的,则为真。
示例
假设我们处于 http://www.example.com/shop/checkout?order=desc&page=1
操作中。
current_page?(action: 'process')
# => false
current_page?(action: 'checkout')
# => true
current_page?(controller: 'library', action: 'checkout')
# => false
current_page?(controller: 'shop', action: 'checkout')
# => true
current_page?(controller: 'shop', action: 'checkout', order: 'asc')
# => false
current_page?(controller: 'shop', action: 'checkout', order: 'desc', page: '1')
# => true
current_page?(controller: 'shop', action: 'checkout', order: 'desc', page: '2')
# => false
current_page?('http://www.example.com/shop/checkout')
# => true
current_page?('http://www.example.com/shop/checkout', check_parameters: true)
# => false
current_page?('/shop/checkout')
# => true
current_page?('http://www.example.com/shop/checkout?order=desc&page=1')
# => true
假设我们处于 http://www.example.com/products
操作中,在产品无效的情况下使用 POST 方法。
current_page?(controller: 'product', action: 'index')
# => false
我们也可以传递符号参数而不是字符串。
来源:显示 | 在 GitHub 上
# File actionview/lib/action_view/helpers/url_helper.rb, line 609 def current_page?(options = nil, check_parameters: false, **options_as_kwargs) unless request raise "You cannot use helpers that need to determine the current " \ "page unless your view context provides a Request object " \ "in a #request method" end return false unless request.get? || request.head? options ||= options_as_kwargs check_parameters ||= options.is_a?(Hash) && options.delete(:check_parameters) url_string = URI::DEFAULT_PARSER.unescape(url_for(options)).force_encoding(Encoding::BINARY) # We ignore any extra parameters in the request_uri if the # submitted URL doesn't have any either. This lets the function # work with things like ?order=asc # the behavior can be disabled with check_parameters: true request_uri = url_string.index("?") || check_parameters ? request.fullpath : request.path request_uri = URI::DEFAULT_PARSER.unescape(request_uri).force_encoding(Encoding::BINARY) if %r{^\w+://}.match?(url_string) request_uri = +"#{request.protocol}#{request.host_with_port}#{request_uri}" end remove_trailing_slash!(url_string) remove_trailing_slash!(request_uri) url_string == request_uri end
link_to(name = nil, options = nil, html_options = nil, &block) 链接
使用由 options
集合创建的 URL,创建给定 name
的锚元素。有关有效选项,请参阅 url_for
文档。也可以传递字符串而不是选项哈希,这将生成一个使用字符串值作为链接 href 的锚元素。使用 :back
符号而不是选项哈希将生成一个指向引荐来源的链接(如果不存在引荐来源,则将使用 JavaScript 返回链接代替)。如果传递 nil
作为名称,则链接本身的值将成为名称。
签名
link_to(body, url, html_options = {})
# url is a String; you can use URL helpers like
# posts_path
link_to(body, url_options = {}, html_options = {})
# url_options, except :method, is passed to url_for
link_to(options = {}, html_options = {}) do
# name
end
link_to(url, html_options = {}) do
# name
end
link_to(active_record_model)
选项
-
:data
- 此选项可用于添加自定义数据属性。
示例
由于它依赖于 url_for
,link_to
支持旧式控制器/操作/id 参数和较新的 RESTful 路由。当前的 Rails 风格尽可能地支持 RESTful 路由,因此请将您的应用程序基于资源并使用
link_to "Profile", profile_path(@profile)
# => <a href="/profiles/1">Profile</a>
或更简洁的
link_to "Profile", @profile
# => <a href="/profiles/1">Profile</a>
代替旧的更冗长、非资源导向的
link_to "Profile", controller: "profiles", action: "show", id: @profile
# => <a href="/profiles/show/1">Profile</a>
同样地,
link_to "Profiles", profiles_path
# => <a href="/profiles">Profiles</a>
比
link_to "Profiles", controller: "profiles"
# => <a href="/profiles">Profiles</a>
当 name 为 nil
时,将显示 href
link_to nil, "http://example.com"
# => <a href="http://www.example.com">http://www.example.com</a>
更简洁的是,当 name
是一个定义了 to_s
方法并返回默认值或模型实例属性的 Active Record 模型时
link_to @profile
# => <a href="http://www.example.com/profiles/1">Eileen</a>
如果您的链接目标难以放入名称参数中,也可以使用块。 ERB
示例
<%= link_to(@profile) do %>
<strong><%= @profile.name %></strong> -- <span>Check it out!</span>
<% end %>
# => <a href="/profiles/1">
<strong>David</strong> -- <span>Check it out!</span>
</a>
CSS 的类和 id 很容易生成
link_to "Articles", articles_path, id: "news", class: "article"
# => <a href="/articles" class="article" id="news">Articles</a>
使用旧参数样式时要小心,因为需要额外的文字哈希
link_to "Articles", { controller: "articles" }, id: "news", class: "article"
# => <a href="/articles" class="article" id="news">Articles</a>
省略哈希会导致错误的链接
link_to "WRONG!", controller: "articles", id: "news", class: "article"
# => <a href="/articles/index/news?class=article">WRONG!</a>
link_to
也可以生成带有锚点或查询字符串的链接
link_to "Comment wall", profile_path(@profile, anchor: "wall")
# => <a href="/profiles/1#wall">Comment wall</a>
link_to "Ruby on Rails search", controller: "searches", query: "ruby on rails"
# => <a href="/searches?query=ruby+on+rails">Ruby on Rails search</a>
link_to "Nonsense search", searches_path(foo: "bar", baz: "quux")
# => <a href="/searches?foo=bar&baz=quux">Nonsense search</a>
您可以设置任何链接属性,例如 target
、rel
、type
link_to "External link", "http://www.rubyonrails.org/", target: "_blank", rel: "nofollow"
# => <a href="http://www.rubyonrails.org/" target="_blank" rel="nofollow">External link</a>
Turbo
Rails
7 默认情况下启用 Turbo。Turbo 提供以下 :data
选项
-
turbo_method: HTTP 动词符号
- 使用给定的 HTTP 动词执行 Turbo 链接访问。建议在执行非GET
请求时使用表单。仅在无法使用表单的情况下使用data-turbo-method
。 -
turbo_confirm: "问题?"
- 使用给定值在链接中添加确认对话框。
示例
link_to "Delete profile", @profile, data: { turbo_method: :delete }
# => <a href="/profiles/1" data-turbo-method="delete">Delete profile</a>
link_to "Visit Other Site", "https://rubyonrails.net.cn/", data: { turbo_confirm: "Are you sure?" }
# => <a href="https://rubyonrails.net.cn/" data-turbo-confirm="Are you sure?">Visit Other Site</a>
已弃用:Rails UJS 属性
在 Rails 7 之前,Rails 默认情况下附带了一个名为 @rails/ujs
的 JavaScript 库。在 Rails 7 之后,此库不再默认启用。此库与以下选项集成
-
method: HTTP 动词符号
- 此修饰符将动态创建 HTML 表单,并立即使用指定的 HTTP 动词提交表单以进行处理。对于让链接在危险操作(例如删除记录)中执行 POST 操作很有用(搜索引擎在抓取您的网站时可以跟踪这些操作)。支持的动词是:post
、:delete
、:patch
和:put
。请注意,如果用户禁用了 JavaScript,请求将回退到使用 GET。如果使用href: '#'
并且用户禁用了 JavaScript,单击链接将没有任何效果。如果您依赖 POST 行为,您应该在控制器的操作中使用请求对象的post?
、delete?
、patch?
或put?
方法检查它。 -
remote: true
- 这将允许@rails/ujs
对相关 URL 发出 Ajax 请求,而不是遵循链接。
@rails/ujs
还与以下 :data
选项集成
-
confirm: "问题?"
- 这将允许@rails/ujs
提示指定的问题(在本例中,结果文本将是问题?
)。如果用户接受,链接将正常处理,否则不采取任何操作。 -
:disable_with
- 此参数的值将用作链接禁用版本的名称。
Rails UJS 示例
link_to "Remove Profile", profile_path(@profile), method: :delete
# => <a href="/profiles/1" rel="nofollow" data-method="delete">Remove Profile</a>
link_to "Visit Other Site", "http://www.rubyonrails.org/", data: { confirm: "Are you sure?" }
# => <a href="http://www.rubyonrails.org/" data-confirm="Are you sure?">Visit Other Site</a>
来源:显示 | 在 GitHub 上
# File actionview/lib/action_view/helpers/url_helper.rb, line 234 def link_to(name = nil, options = nil, html_options = nil, &block) html_options, options, name = options, name, block if block_given? options ||= {} html_options = convert_options_to_data_attributes(options, html_options) url = url_target(name, options) html_options["href"] ||= url content_tag("a", name || url, html_options, &block) end
link_to_if(condition, name, options = {}, html_options = {}, &block) 链接
如果condition
为真,则使用options
创建的 URL 创建给定name
的链接标签,否则仅返回名称。要专门化默认行为,您可以传递一个块,该块接受name
或link_to_if
的完整参数列表。
示例
<%= link_to_if(@current_user.nil?, "Login", { controller: "sessions", action: "new" }) %>
# If the user isn't logged in...
# => <a href="/sessions/new/">Login</a>
<%=
link_to_if(@current_user.nil?, "Login", { controller: "sessions", action: "new" }) do
link_to(@current_user.login, { controller: "accounts", action: "show", id: @current_user })
end
%>
# If the user isn't logged in...
# => <a href="/sessions/new/">Login</a>
# If they are logged in...
# => <a href="/accounts/show/3">my_username</a>
来源:显示 | 在 GitHub 上
# File actionview/lib/action_view/helpers/url_helper.rb, line 498 def link_to_if(condition, name, options = {}, html_options = {}, &block) if condition link_to(name, options, html_options) else if block_given? block.arity <= 1 ? capture(name, &block) : capture(name, options, html_options, &block) else ERB::Util.html_escape(name) end end end
link_to_unless(condition, name, options = {}, html_options = {}, &block) 链接
除非condition
为真,否则使用options
创建的 URL 创建给定name
的链接标签,在这种情况下,仅返回名称。要专门化默认行为(例如,显示登录链接而不是纯文本链接文本),您可以传递一个块,该块接受name
或link_to_unless
的完整参数列表。
示例
<%= link_to_unless(@current_user.nil?, "Reply", { action: "reply" }) %>
# If the user is logged in...
# => <a href="/controller/reply/">Reply</a>
<%=
link_to_unless(@current_user.nil?, "Reply", { action: "reply" }) do |name|
link_to(name, { controller: "accounts", action: "signup" })
end
%>
# If the user is logged in...
# => <a href="/controller/reply/">Reply</a>
# If not...
# => <a href="/accounts/signup">Reply</a>
来源:显示 | 在 GitHub 上
# File actionview/lib/action_view/helpers/url_helper.rb, line 475 def link_to_unless(condition, name, options = {}, html_options = {}, &block) link_to_if !condition, name, options, html_options, &block end
link_to_unless_current(name, options = {}, html_options = {}, &block) 链接
使用由options
集合创建的URL,创建给定name
的链接标签,除非当前请求URI与链接相同,在这种情况下,只返回名称(或如果存在,则返回给定的块)。您可以为link_to_unless_current
提供一个块,该块将专门化默认行为(例如,显示“从这里开始”链接而不是链接的文本)。
示例
假设您有一个导航菜单...
<ul id="navbar">
<li><%= link_to_unless_current("Home", { action: "index" }) %></li>
<li><%= link_to_unless_current("About Us", { action: "about" }) %></li>
</ul>
如果在“about”操作中,它将呈现...
<ul id="navbar">
<li><a href="/controller/index">Home</a></li>
<li>About Us</li>
</ul>
...但是如果在“index”操作中,它将呈现
<ul id="navbar">
<li>Home</li>
<li><a href="/controller/about">About Us</a></li>
</ul>
如果当前操作是给定的操作,则会评估传递给link_to_unless_current
的隐式块。因此,如果我们有一个评论页面,并且想要渲染一个“返回”链接而不是指向评论页面的链接,我们可以这样做...
<%=
link_to_unless_current("Comment", { controller: "comments", action: "new" }) do
link_to("Go back", { controller: "posts", action: "index" })
end
%>
mail_to(email_address, name = nil, html_options = {}, &block) 链接
创建一个指向指定email_address
的mailto链接标签,该标签也用作链接的名称,除非指定了name
。链接的附加HTML属性可以在html_options
中传递。
mail_to
有几种方法可以通过将特殊键传递给html_options
来定制电子邮件本身。
选项
-
:subject
- 预设电子邮件的主题行。 -
:body
- 预设电子邮件的正文。 -
:cc
- 在电子邮件中抄送其他收件人。 -
:bcc
- 在电子邮件中密送其他收件人。 -
:reply_to
- 预设电子邮件的Reply-To
字段。
混淆
在Rails 4.0之前,mail_to
提供了用于对地址进行编码以阻碍电子邮件收集器的选项。要利用这些选项,请安装actionview-encoded_mail_to
gem。
示例
mail_to "me@domain.com"
# => <a href="mailto:me@domain.com">me@domain.com</a>
mail_to "me@domain.com", "My email"
# => <a href="mailto:me@domain.com">My email</a>
mail_to "me@domain.com", cc: "ccaddress@domain.com",
subject: "This is an example email"
# => <a href="mailto:me@domain.com?cc=ccaddress@domain.com&subject=This%20is%20an%20example%20email">me@domain.com</a>
如果您的链接目标难以放入名称参数中,也可以使用块。 ERB
示例
<%= mail_to "me@domain.com" do %>
<strong>Email me:</strong> <span>me@domain.com</span>
<% end %>
# => <a href="mailto:me@domain.com">
<strong>Email me:</strong> <span>me@domain.com</span>
</a>
# File actionview/lib/action_view/helpers/url_helper.rb, line 548 def mail_to(email_address, name = nil, html_options = {}, &block) html_options, name = name, nil if name.is_a?(Hash) html_options = (html_options || {}).stringify_keys extras = %w{ cc bcc body subject reply_to }.map! { |item| option = html_options.delete(item).presence || next "#{item.dasherize}=#{ERB::Util.url_encode(option)}" }.compact extras = extras.empty? ? "" : "?" + extras.join("&") encoded_email_address = ERB::Util.url_encode(email_address).gsub("%40", "@") html_options["href"] = "mailto:#{encoded_email_address}#{extras}" content_tag("a", name || email_address, html_options, &block) end
phone_to(phone_number, name = nil, html_options = {}, &block) 链接
创建指向指定phone_number
的TEL锚链接标签。点击链接时,将打开默认的拨打电话应用程序,并预先填充电话号码。
如果未指定name
,则phone_number
将用作链接的名称。
支持country_code
选项,该选项会在链接的电话号码前加上一个加号和给定的国家代码。例如,country_code: "01"
会在链接的电话号码前加上+01
。
可以通过html_options
传递链接的附加HTML属性。
选项
-
:country_code
- 在电话号码前加上国家代码
示例
phone_to "1234567890"
# => <a href="tel:1234567890">1234567890</a>
phone_to "1234567890", "Phone me"
# => <a href="tel:1234567890">Phone me</a>
phone_to "1234567890", country_code: "01"
# => <a href="tel:+011234567890">1234567890</a>
如果您的链接目标难以放入名称参数中,也可以使用块。ERB示例
<%= phone_to "1234567890" do %>
<strong>Phone me:</strong>
<% end %>
# => <a href="tel:1234567890">
<strong>Phone me:</strong>
</a>
# File actionview/lib/action_view/helpers/url_helper.rb, line 743 def phone_to(phone_number, name = nil, html_options = {}, &block) html_options, name = name, nil if name.is_a?(Hash) html_options = (html_options || {}).stringify_keys country_code = html_options.delete("country_code").presence country_code = country_code.nil? ? "" : "+#{ERB::Util.url_encode(country_code)}" encoded_phone_number = ERB::Util.url_encode(phone_number) html_options["href"] = "tel:#{country_code}#{encoded_phone_number}" content_tag("a", name || phone_number, html_options, &block) end
sms_to(phone_number, name = nil, html_options = {}, &block) 链接
创建指向指定phone_number
的SMS锚链接标签。点击链接时,将打开默认的短信应用程序,并准备好向链接的电话号码发送消息。如果指定了body
选项,则消息内容将预设为body
。
如果未指定name
,则phone_number
将用作链接的名称。
支持country_code
选项,该选项会在链接的电话号码前加上一个加号和给定的国家代码。例如,country_code: "01"
会在链接的电话号码前加上+01
。
可以通过html_options
传递链接的附加HTML属性。
选项
-
:country_code
- 在电话号码前加上国家代码。 -
:body
- 预设消息内容。
示例
sms_to "5155555785"
# => <a href="sms:5155555785;">5155555785</a>
sms_to "5155555785", country_code: "01"
# => <a href="sms:+015155555785;">5155555785</a>
sms_to "5155555785", "Text me"
# => <a href="sms:5155555785;">Text me</a>
sms_to "5155555785", body: "I have a question about your product."
# => <a href="sms:5155555785;?body=I%20have%20a%20question%20about%20your%20product">5155555785</a>
如果您的链接目标难以放入名称参数中,也可以使用块。ERB示例
<%= sms_to "5155555785" do %>
<strong>Text me:</strong>
<% end %>
# => <a href="sms:5155555785;">
<strong>Text me:</strong>
</a>
# File actionview/lib/action_view/helpers/url_helper.rb, line 692 def sms_to(phone_number, name = nil, html_options = {}, &block) html_options, name = name, nil if name.is_a?(Hash) html_options = (html_options || {}).stringify_keys country_code = html_options.delete("country_code").presence country_code = country_code ? "+#{ERB::Util.url_encode(country_code)}" : "" body = html_options.delete("body").presence body = body ? "?&body=#{ERB::Util.url_encode(body)}" : "" encoded_phone_number = ERB::Util.url_encode(phone_number) html_options["href"] = "sms:#{country_code}#{encoded_phone_number};#{body}" content_tag("a", name || phone_number, html_options, &block) end