模型中的 Rails 动态搜索

Posted

技术标签:

【中文标题】模型中的 Rails 动态搜索【英文标题】:Rails Dynamic Search in a Model 【发布时间】:2018-01-08 13:55:45 【问题描述】:

我有以下型号:

具有 :year、:model 和 :car_brand_id 字段的汽车。 CarBrand 只有一个 :name 字段和 has_many :cars

在视图中,我有一个带有 ransack 的搜索表单,如下所示:

<%= search_form_for(@q, url: search_result_path) do |f| %>

  <%= f.select(:year_eq, 1960..(Date.today.year+1), prompt: 'year', class: "grey-text") %>
  <%= f.collection_select :car_brand_id_eq, CarBrand.all, :id, :name, prompt: 'brand', class: "grey-text" %>
  <%= f.collection_select :model_eq, Car.models, :model, :model, prompt: 'model', class: "grey-text " %>
  <%= f.button "Search" %>

<% end %>

我想让表单搜索动态化,例如,如果用户在表单中选择特定年份,则下一个字段 (:car_brand_id) 仅返回选择之前选择的年份的选项,依此类推与下一个字段。提前致谢。

【问题讨论】:

没有“rails”方法可以做到这一点。您必须使用 javascript 对您的 Rails 服务器进行 ajax 调用以获取内容,然后更新 DOM。谷歌“javascript ajax”、“javascript onchange 事件”和“使用 javascript 更改 DOM”开始。如果您熟悉它,我建议使用jquery。当然,如果您遇到问题,您可以随时带着损坏的代码返回这里 - 我们很乐意帮助您修复它。 【参考方案1】:

我对此类问题特别感兴趣,因为我花了很长时间才弄清楚类似的事情。所以一般应该是这样的:

    使用一个实例变量设置您的:car_brand_eqcollection_select,您可以通过ajax 调用和一个可以引用它的类来更新该实例变量。变化:

    <%= f.collection_select :car_brand_eq, CarBrand.all... 
    

    到:

    <%= f.collection_select :car_brand_eq, @car_brands, :id, :name, prompt: 'brand', class: "grey-text car-brand-collection" %>
    

    设置您的 AJAX 调用:

    要么获取 &lt;%= f.select(:year_eq... 的 id 以在 jquery 中使用,要么为其添加唯一的类名:

    <%= f.select(:year_eq, 1960..(Date.today.year+1), prompt: 'year', class: "grey-text year-selector") %>
    

    然后是脚本:

    <script>
      $(document).on("change", ".year-selector", function () 
        $.ajax(
          url: "/car_brands/search.js",
          // now pass params[:year] as a query string
          data:  year: $(".year-selector").val() ,
          type: "GET"
        );
      );
    </script>
    

    现在设置您的search_car_brands_path 路由,然后设置car_brands_controller.rb 中的逻辑,或您将使用的任何其他控制器:

    routes.rb (an explantion of this routes logic here)

    resources :car_brands do
      collection do
        # search_car_brands_path
        get :search
      end
    end
    

    car_brands_controller.rb

    ...
    # GET /car_brands/search
    # search_car_brands_path
    def search
      # not knowing how exactly you filter CarBrands by year, I'm guessing:
      @car_brands = CarBrand.where(year: params[:year])
    end
    

    最后。现在您只需要在以下位置设置 search.js.erb:

    views/car_brands/search.js.erb

    // grab that car-brand-collection selector from step 1 & update it
    $(".car-brand-collection").html("<%= f.collection_select :car_brand_eq, @car_brands, :id, :name, prompt: 'brand', class: "grey-text car-brand-collection" %>");
    

这些是步骤。我没有测试它们,但你应该可以从这里解决。

【讨论】:

以上是关于模型中的 Rails 动态搜索的主要内容,如果未能解决你的问题,请参考以下文章

Rails 跨多个模型搜索

如何更改 Rails 脚手架中的默认模型模板?

如何编写迁移以重命名 Rails 中的 ActiveRecord 模型及其表?

在 Rails 应用程序中将模型搜索逻辑放在哪里?

Sunspot Solr Rails - 使用“with”搜索多个模型

在 Rails 中将模型更新为另一个模型