从网址中删除空参数

时间:2018-06-28 23:04:03

标签: ruby-on-rails ruby-on-rails-5

我在Rails应用程序中具有“高级搜索”功能,用户可以在其中过滤结果。该页面位于https://myurl/users/search。搜索表单过滤器工作正常,它重定向到https://myurl/users,这是显示过滤结果的索引页。

我唯一关心的是,当用户没有为https://myurl/users?cert=CCNA&ed=&ex=&job=NetworkEng&lang=&maj=&s=&u=这样的参数选择任何值时,URL中会填充所有空参数

我想看到的只是具有价值的参数。例如https://myurl/users?cert=CCNA&job=NetworkEng

这是我所见的一个例子。这将创建一个带有用户选择的搜索词的按钮,当他们单击该按钮时,将删除特定的搜索过滤器。

如果可能的话,我只想让用户实际填充的参数显示在url中,并隐藏所有其他参数。我在想,也许我必须以某种方式使用hidden_field_tag或在显示在link_to中之前检查每个值是否存在?

当前,如果我没有在link_to中列出所有参数,那么当用户单击按钮以删除一个搜索过滤器时,所有参数都将被删除。

<% if params[:job].present? %>
  <%= link_to  users_path( c: params[:c], ex: params[:ex], s: params[:s], sk: params[:sk], lang: params[:lang], 
                           cert: params[:cert], u: params[:u], relo: params[:relo], ed: params[:ed], maj: params[:maj], user_search: params[:user_search] ) , class: "btn btn-outline-danger" do %>
    <i class="fa fa-times"></i> <%= "#{params[:job]}"  %>
  <% end %>        
<% end %>      

<% if params[:user_search].present? %>
  <%= link_to  users_path( c: params[:c], ex: params[:ex], s: params[:s], sk: params[:sk], lang: params[:lang], 
                           cert: params[:cert], u: params[:u], relo: params[:relo], ed: params[:ed], maj: params[:maj], job: params[:job] ) , class: "btn btn-outline-danger" do %>
    <i class="fa fa-times"></i> <%= "#{params[:user_search]}"  %>
  <% end %>        
<% end %>   

users_controller中内容的示例

  if params[:user_search].present? 
    @users = @users.by_keyword(params[:user_search])
  end 

我的用户模型中的范围示例

  scope :by_will_relocate, ->(relo) { where(will_relocate: true).order(updated_at: :desc) if relo.present? }
  scope :by_current_job_title, ->(job) { where('current_job_title LIKE ?', "%#{job}%").order(updated_at: :desc) if job.present? }

   scope :by_keyword, ->(k) { by_skill(k) | by_language(k) | by_certification_or_cert_authority(k) | by_education_level(k) | by_university_major(k)}

1 个答案:

答案 0 :(得分:0)

您的问题是,您是从params中提取密钥,而不考虑其值或是否已指定它们:

c: params[:c], ex: params[:ex], s: params[:s], sk: params[:sk], lang: params[:lang], cert: params[:cert], u: params[:u], relo: params[:relo], ed: params[:ed], maj: params[:maj]

如果您想忽略未指定的内容,请使用slice

params.to_unsafe_h.slice(:c, :ex, :s, :sk, :lang, :cert, :u, :relo, :ed, :maj)
params.to_unsafe_h.slice(*%i[c ex s sk lang cert u relo ed maj])

为了安全起见,您可能还希望删除在那里但明确地nil的值:

base = params.to_unsafe_h
             .slice(*%i[c ex s sk lang cert u relo ed maj])
             .select { |_, v| !v.nil? }

然后,当您建立链接时,请合并其他内容:

<% if params[:job].present? %>
  <%= link_to users_path(base.merge(user_search: params[:user_search])), class: "btn btn-outline-danger" do %>
    <i class="fa fa-times"></i> <%= "#{params[:job]}"  %>
  <% end %>        
<% end %>

这也通过将所有通用性放入users_path中来清理base调用中的重复项。

您也可以使用params.permit(:c, :ex, ...)而不是params.to_unsafe_h,但无论如何都可以对其进行过滤。

此外,您确定已将:user_search:job参数添加到正确的链接吗?似乎您的第一个条件将包含job: params[:job]而不是user_search: params[:user_search]