【问题标题】:Rendering a dynamic select list in simple_form以 simple_form 呈现动态选择列表
【发布时间】:2019-09-25 19:30:45
【问题描述】:

我在 JS/Ajax 方面相对较新,我注意到如何根据先前以相同 (simple_) 形式插入的数据来呈现动态选项。

背景:通过该应用,自行车连锁店(“连锁店”)可以出租

  • 名称为“自行车 1”或“黄色自行车”(“自行车”)的自行车,
  • 通过选择自行车类型,例如山地自行车、城市自行车等 ('bike_types) 和
  • 自行车选项,例如头盔等('bike_options')
  • 取决于各个自行车商店 ('bike_stores')
  • 此自行车和选项的租赁将全部记录在订单(“订单”)中
  • 订单和自行车之间的关系是多对多的,因此 - 我创建了一个表来连接这个('order_bikes')

悬而未决的问题:我能够通过 JS 获取 bike_type_id。如何使用这个 bike_type 的 id 以相同的形式显示属于该 bike_type 的自行车?

如前所述,不幸的是,我对在 Rails 应用程序中使用 JS/Ajax 并不十分熟悉,因此如果可以在应编写建议代码的位置添加文件路径(例如 app /javascript/components/order.js 等)

最后说明:

  • 在租赁过程之前,连锁店所有者首先创建了他/她的 (i)bike_stores、(ii)bike_types、(iii)bike 和 (iv)bike_options,这部分应用程序正在运行。因此,他/她只需从之前创建的现有库存中选择bike_types/bikes/options。
  • 我通过省略bike_options 来限制问题的范围,这主要是为了提供一些上下文以了解数据库架构的构建。

型号

class Order < ApplicationRecord
  belongs_to :bike_store
  has_many :bike_types, through: :bike_store
  has_many :order_bikes, inverse_of: :order, dependent: :destroy
  accepts_nested_attributes_for :order_bikes, allow_destroy: true
end


class OrderBike < ApplicationRecord
  belongs_to :bike
  belongs_to :order
  accepts_nested_attributes_for :bike
end


class Bike < ApplicationRecord
  belongs_to :bike_type
  validates :name, presence: true
  has_many :order_bikes
  has_many :orders, through: :order_bikes
end


class BikeType < ApplicationRecord
  belongs_to :bike_store
  has_many :bikes, dependent: :destroy
  accepts_nested_attributes_for :bikes, allow_destroy: true
  has_many :bike_options, dependent: :destroy
  accepts_nested_attributes_for :bike_options, allow_destroy: true
  validates :name, :bike_count, presence: true
end

class BikeStore < ApplicationRecord
  has_many :bike_types, dependent: :destroy
  has_many :orders, dependent: :destroy
end

订单控制器

class OrdersController < ApplicationController

  def new
    @bike_store = BikeStore.find(params[:bike_store_id])
    @order = Order.new
    @order.order_bikes.build
    @bike_type_list = @bike_store.bike_types
  end

  def create
    @order = Order.new(order_params)
    @bike_store = BikeStore.find(params[:bike_store_id])
    @order.bike_store = @bike_store
    @order.save
    redirect_to root_path
  end

private
  def order_params
    params.require(:order).permit(:arrival, :departure,
      order_bikes_attributes: [:id, :bike_id,:bike_quantity, :_destroy,
        bikes_attributes: [:id, :name,
          bike_types_attributes: [:id, :name]]])
  end
end

views/orders/new.html.erb

<%= simple_form_for [@bike_store, @order] do |f|%>

  <%= f.simple_fields_for :order_bikes do |order_bike| %>
    <%= order_bike.input :bike_quantity %>

      <%= order_bike.simple_fields_for :bikes do |bike| %>

        #fist a bike_type will be classified, see below
        <%= bike.select :bike_type_id, options_for_select(@bike_type_list.collect{|type|[type.name, type.id]}) %>
      <% end %>

      #then a dropdown of bikes belonging to above chose bike_type need to be displayed below.
      <%= order_bike.association :bike, collection [bike_type.bikes] %>
  <% end %>

  <%= f.input :arrival %>
  <%= f.input :departure %>
  <%= f.submit %>
<% end %>

<script>
  // return id bike_type
  function selectType(){
  const bikeType = document.getElementById("order_order_bikes_attributes_0_bikes_bike_type_id").value;
  }
</script>

【问题讨论】:

    标签: javascript jquery ruby-on-rails ajax


    【解决方案1】:

    哇,弄清楚这一点很痛苦/花了一些时间......对于看到这个的人,我找到了一个可行的答案,希望它可以节省你一些时间。

    我很确定这不是最优雅的解决方案,所以请随时优化。我是用 Ajax 做的,请在下面找到解决方案:

    在视图中

    <%= simple_form_for [@bike_store, @order] do |f|%>
    
      <%= f.simple_fields_for :order_bikes do |order_bike| %>
        <%= order_bike.input :bike_quantity %>
    
          <%= order_bike.simple_fields_for :bikes do |bike| %>
    
            #fist a bike_type will be classified, see below
            <%= bike.select :bike_type_id, options_for_select(@bike_type_list.collect{|type|[type.name, type.id]}) %>
          <% end %>
    
          #then a dropdown of bikes belonging to above chose bike_type need to be displayed below.
          <%= order_bike.association :bike, collection [bike_type.bikes] %>
      <% end %>
    
      <%= f.input :arrival %>
      <%= f.input :departure %>
      <%= f.submit %>
    <% end %>
    
    <script>
    
    $(document).on("change", "#order_order_bikes_attributes_0_bikes_bike_type_id", function(){
        var bike_type = $(this).val();
    
       $.ajax({
        url: "/bike_stores/<%= @bike_store.id %>/orders/new",
        method: "GET",
        dataType: "json",
        data: {bike_type: bike_type},
        error: function (xhr, status, error) {
          console.error('AJAX Error: ' + status + error);
        },
        success: function (response) {
          console.log(response);
          var bikes = response["bikes"];
          $("#order_order_bikes_attributes_0_bikes_bike_type_id").empty();
    
          $("#order_order_bikes_attributes_0_bike_id").append('<option>Select bike</option>');
          for(var i=0; i< bikes.length; i++){
            $("#order_order_bikes_attributes_0_bike_id").append('<option value="' + bikes[i]["id"] + '">' + bikes[i]["name"] + '</option>');
          }
        }
      });
    });
    </script>
    

    订单控制器

      def new
        @bike_store = BikeStore.find(params[:bike_store_id])
        @order = Order.new
        @order.order_bikes.build
        @bike_type_list = @bike_store.bike_types
    
        if params[:bike_type].present?
          @bikess = BikeType.find(params[:bike_type]).bikes
        end
        if request.xhr?
          respond_to do |format|
            format.json {
            render json: {bikes: @bikes}
          }
        end
      end
    end
      end
    

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-11
    • 2017-04-23
    • 2012-04-18
    • 2017-03-25
    • 2012-02-27
    • 1970-01-01
    相关资源
    最近更新 更多