如果所需的密钥不存在,如何在 link_to 中传递参数而不中断?
How do you pass params in a link_to without breaking if a required key is not present?
首先,我可以正常工作,但我想知道是否有更好的方法。
我有很多索引页面,用户可以在其中应用过滤器,然后将结果导出到 .csv
或 .xls
文件。
我所做的是将 params
存在的任何内容(在应用过滤器之后)转发到再次查询数据库的控制器操作,并将结果发送到构建文件的服务,就像这样:
link_to:
<li>
<% if params.dig(:q).present? %>
<%= link_to export_payments_admin_payments_path(params: { q: params.require(:q).permit(params[:q].keys, status_in: [], payment_type_in: [])}, format: "csv") do %>
<span class="glyphicon glyphicon-download" aria-hidden="true"></span>
Export
<% end %>
<% else %>
<%= link_to export_payments_admin_payments_path(format: "csv") do %>
<span class="glyphicon glyphicon-download" aria-hidden="true"></span>
Export
<% end %>
<% end %>
</li>
控制器动作:
def export_payments
@pre_search = current_account.payments.includes(:user)
@search = @pre_search.ordered.ransack(params[:q])
@payments = @search.result.paginate(page: params[:page], per_page: 20)
respond_to do |format|
format.csv do
send_data FileManager::PaymentsExporter.new(@payments).call,
filename: "payments_#{Date.today}" + ".csv"
end
end
end
如您所知,link_to
必须包含在条件语句中,因为如果我 require(:q)
但它不存在(未应用过滤器),视图将中断,因为必需 :q
密钥不存在。
有更好的方法吗?我试过删除 require(:q)
但如果我这样做的话根本不会传递任何参数。
您应该将所有这些逻辑移至控制器或助手。
首先创建一个方法来挂载在 link 中发送的参数,这样您就不需要将其包装成条件
# controller
def export_payments
...
@q_params = q_params
...
end
def q_params
if params.dig(:q).present?
params.require(:q).permit(params[:q].keys, status_in: [], payment_type_in: [])
else
{}
end
end
然后,使用方法渲染 link:
# view
<%= link_to export_payments_admin_payments_path(format: "csv", params: { q: @q_params }) do %>
<span class="glyphicon glyphicon-download" aria-hidden="true"></span>
Export
<% end %>
首先,我可以正常工作,但我想知道是否有更好的方法。
我有很多索引页面,用户可以在其中应用过滤器,然后将结果导出到 .csv
或 .xls
文件。
我所做的是将 params
存在的任何内容(在应用过滤器之后)转发到再次查询数据库的控制器操作,并将结果发送到构建文件的服务,就像这样:
link_to:
<li>
<% if params.dig(:q).present? %>
<%= link_to export_payments_admin_payments_path(params: { q: params.require(:q).permit(params[:q].keys, status_in: [], payment_type_in: [])}, format: "csv") do %>
<span class="glyphicon glyphicon-download" aria-hidden="true"></span>
Export
<% end %>
<% else %>
<%= link_to export_payments_admin_payments_path(format: "csv") do %>
<span class="glyphicon glyphicon-download" aria-hidden="true"></span>
Export
<% end %>
<% end %>
</li>
控制器动作:
def export_payments
@pre_search = current_account.payments.includes(:user)
@search = @pre_search.ordered.ransack(params[:q])
@payments = @search.result.paginate(page: params[:page], per_page: 20)
respond_to do |format|
format.csv do
send_data FileManager::PaymentsExporter.new(@payments).call,
filename: "payments_#{Date.today}" + ".csv"
end
end
end
如您所知,link_to
必须包含在条件语句中,因为如果我 require(:q)
但它不存在(未应用过滤器),视图将中断,因为必需 :q
密钥不存在。
有更好的方法吗?我试过删除 require(:q)
但如果我这样做的话根本不会传递任何参数。
您应该将所有这些逻辑移至控制器或助手。
首先创建一个方法来挂载在 link 中发送的参数,这样您就不需要将其包装成条件
# controller
def export_payments
...
@q_params = q_params
...
end
def q_params
if params.dig(:q).present?
params.require(:q).permit(params[:q].keys, status_in: [], payment_type_in: [])
else
{}
end
end
然后,使用方法渲染 link:
# view
<%= link_to export_payments_admin_payments_path(format: "csv", params: { q: @q_params }) do %>
<span class="glyphicon glyphicon-download" aria-hidden="true"></span>
Export
<% end %>