Rails 5:为什么在使用变量设置部分 ID 中的输入时会收到 500 响应,而在使用字符串文字时却不会?
Rails 5: Why do I get a 500 response when setting an input in a partial's id with a variable but not when using a string literal?
我有一个已部分提取的表格。
<%= form_with url: filtered_tags_path, class: 'filter-box' do %>
<%= text_field_tag(:filter_by, '', id: 'filter-text-field', autocomplete: 'off') %>
<% end %>
<script>watch_form()</script>
application.js
中有一个脚本可以监视文本字段中的变化并在每次击键后触发请求:
function watch_form() {
document.getElementById('filter-text-field').addEventListener('keyup', function(){
Rails.fire(this.form, 'submit')
})
}
对应的动作是这样的:
def create
@labels = Label.by_search_term(params[:filter_by])
respond_to do |format|
format.js
end
end
使用此模板:
document.querySelector('.filter-results')
.innerHTML = "<%= escape_javascript(render partial: 'filtered_results') %>"
呈现:
<% if @labels.present? %>
<% @labels.each do |label| %>
<%= label_link(name: label.name, is_remote: true) %>
<% end %>
<% else %>
<div class="badge no-tags-badge">No tags found</div>
<% end %>
简而言之,渲染了一系列按钮(包裹在表单中)。例如:
<form class="button_to" method="post" action="/issues?labels%5B%5D=ready" data-remote="true">
<input class="label-badge" type="submit" value="+ ready">
<input type="hidden" name="authenticity_token" value="yvWh51r/xHqLPb5V/qdfeiar/j9fqd/8FoZM0jnRFUFEHkdU5WlgVjyaIQi9viiiSfckjJypOhMnKAh29wjY3w==">
</form>
当我点击一个按钮时,它会发送它的请求,我会得到一个成功的响应。
我想要两个单独的表格。我的第一步是将表单文本字段的 id
换成一个变量。
<%= form_with url: filtered_tags_path, class: 'filter-box' do %>
<%= text_field_tag(:filter_by, '', id: filter_field_id, autocomplete: 'off') %>
<% end %>
<script>watch_form()</script>
像这样将它传递给部分:
<div class="filter-form">
<%= render partial: 'filter_form', locals: { filter_field_id: 'filter-text-field' } %>
</div>
表单的行为与以前完全一样。为每次击键呈现按钮。除了真实性标记外,示例按钮看起来完全一样。
<form class="button_to" method="post" action="/issues?labels%5B%5D=ready" data-remote="true">
<input class="label-badge" type="submit" value="+ ready">
<input type="hidden" name="authenticity_token" value="0xjeK53JZSF0nSA2kUT2MREgaCeQ8RlmK2wqcd2sCIZd8ziYIl/BDcM6v2vSXYHpfnyylFPx/Ikawm7VE3XFGA==">
</form>
没有任何迹象表明有任何不同,但这次,在单击按钮时,我得到了 500
响应。
在控制台中,我看到:
rails-ujs.self-d109d8c5c0194c8ad60b8838b2661c5596b5c955987f7cd4045eb2fb90ca5343.js?body=1:212
POST http://localhost:3000/issues?labels%5B%5D=documentation&labels%5B%5D=ready 500 (Internal Server Error)
Rails.ajax @ rails-ujs.self-d109d…a5343.js?body=1:212
Rails.handleRemote @ rails-ujs.self-d109d…a5343.js?body=1:568
(anonymous) @ rails-ujs.self-d109d…a5343.js?body=1:169
现在,我完全迷路了。我已经尝试将我的 javascript 绑定到 turbolinks:load
事件侦听器,但这并没有什么不同。
我唯一能想到的是与真品令牌有关。
将字符串文字作为 id 传递和使用变量有什么区别?为什么我的改变会破坏事物?我需要做什么才能让它发挥作用?
更新
我发现点击页面上的任何类似按钮,除了输入更改时呈现的按钮外,都会产生 500
响应。
更新 2
rails 控制台中的错误:
ActionView::Template::Error (undefined local variable or method `filter_field_id' for #<#<Class:0x00007fa891909b60>:0x00007fa88bf7ef78>
Did you mean? file_field):
1: <%= form_with url: filtered_tags_path, class: 'filter-box' do %>
2: <%= text_field_tag(:filter_by, '', id: filter_field_id, autocomplete: 'off') %>
3: <% end %>
4: <script>watch_form()</script>
app/views/issues/_filter_form.html.erb:2:in `block in _app_views_issues__filter_form_html_erb___4066184210884757332_70181011505480'
app/views/issues/_filter_form.html.erb:1:in `_app_views_issues__filter_form_html_erb___4066184210884757332_70181011505480'
app/views/issues/create.js.erb:14:in `_app_views_issues_create_js_erb__4388147431667736133_70180939735900'
由此我可以看出,当我在 create.js.erb
中渲染局部变量时,我没有传入局部变量。所以我将其修改为:
document.querySelector('.filter-form')
.innerHTML = "<%= escape_javascript(render 'filter_form', locals: { :filter_field_id=> 'filter-text-field' }) %>"
但我仍然遇到同样的错误。 undefined local variable or method 'filter_field_id'
不使用 partial
时传递局部变量是不同的。 create.js.erb file
.
中不需要 locals
# Instead of <%= render partial: "account", locals: { account: @buyer } %>
<%= render "account", account: @buyer %>
因此您的代码应该是:
document.querySelector('.filter-form')
.innerHTML = "<%= escape_javascript(render 'filter_form', filter_field_id: 'filter-text-field' ) %>"
或
document.querySelector('.filter-form')
.innerHTML = "<%= escape_javascript(render partial: 'filter_form', locals: { filter_field_id: 'filter-text-field' }) %>"
我有一个已部分提取的表格。
<%= form_with url: filtered_tags_path, class: 'filter-box' do %>
<%= text_field_tag(:filter_by, '', id: 'filter-text-field', autocomplete: 'off') %>
<% end %>
<script>watch_form()</script>
application.js
中有一个脚本可以监视文本字段中的变化并在每次击键后触发请求:
function watch_form() {
document.getElementById('filter-text-field').addEventListener('keyup', function(){
Rails.fire(this.form, 'submit')
})
}
对应的动作是这样的:
def create
@labels = Label.by_search_term(params[:filter_by])
respond_to do |format|
format.js
end
end
使用此模板:
document.querySelector('.filter-results')
.innerHTML = "<%= escape_javascript(render partial: 'filtered_results') %>"
呈现:
<% if @labels.present? %>
<% @labels.each do |label| %>
<%= label_link(name: label.name, is_remote: true) %>
<% end %>
<% else %>
<div class="badge no-tags-badge">No tags found</div>
<% end %>
简而言之,渲染了一系列按钮(包裹在表单中)。例如:
<form class="button_to" method="post" action="/issues?labels%5B%5D=ready" data-remote="true">
<input class="label-badge" type="submit" value="+ ready">
<input type="hidden" name="authenticity_token" value="yvWh51r/xHqLPb5V/qdfeiar/j9fqd/8FoZM0jnRFUFEHkdU5WlgVjyaIQi9viiiSfckjJypOhMnKAh29wjY3w==">
</form>
当我点击一个按钮时,它会发送它的请求,我会得到一个成功的响应。
我想要两个单独的表格。我的第一步是将表单文本字段的 id
换成一个变量。
<%= form_with url: filtered_tags_path, class: 'filter-box' do %>
<%= text_field_tag(:filter_by, '', id: filter_field_id, autocomplete: 'off') %>
<% end %>
<script>watch_form()</script>
像这样将它传递给部分:
<div class="filter-form">
<%= render partial: 'filter_form', locals: { filter_field_id: 'filter-text-field' } %>
</div>
表单的行为与以前完全一样。为每次击键呈现按钮。除了真实性标记外,示例按钮看起来完全一样。
<form class="button_to" method="post" action="/issues?labels%5B%5D=ready" data-remote="true">
<input class="label-badge" type="submit" value="+ ready">
<input type="hidden" name="authenticity_token" value="0xjeK53JZSF0nSA2kUT2MREgaCeQ8RlmK2wqcd2sCIZd8ziYIl/BDcM6v2vSXYHpfnyylFPx/Ikawm7VE3XFGA==">
</form>
没有任何迹象表明有任何不同,但这次,在单击按钮时,我得到了 500
响应。
在控制台中,我看到:
rails-ujs.self-d109d8c5c0194c8ad60b8838b2661c5596b5c955987f7cd4045eb2fb90ca5343.js?body=1:212
POST http://localhost:3000/issues?labels%5B%5D=documentation&labels%5B%5D=ready 500 (Internal Server Error)
Rails.ajax @ rails-ujs.self-d109d…a5343.js?body=1:212
Rails.handleRemote @ rails-ujs.self-d109d…a5343.js?body=1:568
(anonymous) @ rails-ujs.self-d109d…a5343.js?body=1:169
现在,我完全迷路了。我已经尝试将我的 javascript 绑定到 turbolinks:load
事件侦听器,但这并没有什么不同。
我唯一能想到的是与真品令牌有关。
将字符串文字作为 id 传递和使用变量有什么区别?为什么我的改变会破坏事物?我需要做什么才能让它发挥作用?
更新
我发现点击页面上的任何类似按钮,除了输入更改时呈现的按钮外,都会产生 500
响应。
更新 2
rails 控制台中的错误:
ActionView::Template::Error (undefined local variable or method `filter_field_id' for #<#<Class:0x00007fa891909b60>:0x00007fa88bf7ef78>
Did you mean? file_field):
1: <%= form_with url: filtered_tags_path, class: 'filter-box' do %>
2: <%= text_field_tag(:filter_by, '', id: filter_field_id, autocomplete: 'off') %>
3: <% end %>
4: <script>watch_form()</script>
app/views/issues/_filter_form.html.erb:2:in `block in _app_views_issues__filter_form_html_erb___4066184210884757332_70181011505480'
app/views/issues/_filter_form.html.erb:1:in `_app_views_issues__filter_form_html_erb___4066184210884757332_70181011505480'
app/views/issues/create.js.erb:14:in `_app_views_issues_create_js_erb__4388147431667736133_70180939735900'
由此我可以看出,当我在 create.js.erb
中渲染局部变量时,我没有传入局部变量。所以我将其修改为:
document.querySelector('.filter-form')
.innerHTML = "<%= escape_javascript(render 'filter_form', locals: { :filter_field_id=> 'filter-text-field' }) %>"
但我仍然遇到同样的错误。 undefined local variable or method 'filter_field_id'
不使用 partial
时传递局部变量是不同的。 create.js.erb file
.
locals
# Instead of <%= render partial: "account", locals: { account: @buyer } %>
<%= render "account", account: @buyer %>
因此您的代码应该是:
document.querySelector('.filter-form')
.innerHTML = "<%= escape_javascript(render 'filter_form', filter_field_id: 'filter-text-field' ) %>"
或
document.querySelector('.filter-form')
.innerHTML = "<%= escape_javascript(render partial: 'filter_form', locals: { filter_field_id: 'filter-text-field' }) %>"