Визуализация динамического списка выбора в simple_form - PullRequest
1 голос
/ 25 сентября 2019

Я относительно новичок в JS / Ajax, и я точно уверен, как отображать динамические параметры, основываясь на предыдущих вставленных данных в той же (простой_) форме.

Контекст: Через приложение сеть магазинов велосипедов («цепочки») может сдавать в аренду

  • велосипеды с названиями, такими как «велосипед 1» или «желтый»bike "('велосипеды'),
  • путем выбора типа велосипеда, такого как горный велосипед, городской велосипед и т. д. ('bike_types) и
  • опции велосипеда, такие как шлемы и т. д. (' bike_options"')
  • , которые зависят от отдельного магазина велосипедов (' bike_stores ') *
  • эта аренда велосипедов и опций будет зафиксирована в заказе («заказы»)
  • отношения между заказами и мотоциклами многие-ко-многим, поэтому - я создал таблицу, чтобы соединить это ('order_bikes')

Нерешенный вопрос: Я могучтобы получить bike_type_id через JS.Как я могу использовать этот идентификатор bike_type, чтобы показать велосипеды, принадлежащие этому bike_type, в той же форме?

Как уже упоминалось, к сожалению, я не очень знаком с использованием JS / Ajax в приложениях rails, поэтому было бы очень полезно и полезно, если бы можно было добавить пути к файлам, где должен быть написан предложенный код(например, app / javascript / components / order.js и т. д.)

Заключительные замечания:

  • Перед арендой владелец сети сначала создал свою /ее (i) bike_stores, (ii) bike_types, (iii) велосипеды и (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>

1 Ответ

0 голосов
/ 26 сентября 2019

Ничего себе понять это было больно / заняло некоторое время .... Для людей, которые смотрят на это, я нашел рабочий ответ, надеюсь, это сэкономит вам время.

Я уверен, что это не самое элегантное решение, поэтому, пожалуйста, не стесняйтесь оптимизировать.Я сделал это с 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...