Я могу создать форму заказа, где пользователь может заполнить bike_type и, следовательно, форма отображает велосипеды, принадлежащие этому bike_type.
- Заказы связаны с велосипедами через таблицу соединений (так как между ними существует отношение многих ко многим).
- Велосипед принадлежит к байту_типа
- Abike_type принадлежит к bike_store
Issue
Когда форма перерисовывается, например, (i) повышается валидация, поэтому «новое» действие отображается снова или(ii) когда я хочу изменить заказ:
- Все поля заполняются предыдущими данными, кроме полей для bike_type и bike (они пусты).
Код
Контроллер заказов
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
@bikes = []
# Display bikes for category
if params[:bike_type].present?
@bikes = BikeType.find(params[:bike_type]).bikes
end
if request.xhr?
respond_to do |format|
format.json {
render json: {bikes: @bikes}
}
end
end
authorize @order
end
def create
@order = Order.new(order_params)
@bike_store = BikeStore.find(params[:bike_store_id])
@order.bike_store = @bike_store
authorize @order
@order.save
if @order.save
redirect_to bike_store_path(@bike_store)
else
@bike_type_list = @bike_store.bike_types
render 'new'
end
end
def edit
@bike_store = BikeStore.find(params[:bike_store_id])
@order = Order.find(params[:id])
@bike_type_list = @bike_store.bike_types
@bikes = @order.bikes
authorize @order
end
def update
@bike_store = BikeStore.find(params[:bike_store_id])
@order = Order.find(params[:id])
@bikes = @order.bikes
if @order.update(order_params)
redirect_to redirect_to bike_store_path(@bike_store)
else
render 'edit'
end
authorize @order
end
private
def set_order
@order = Order.find(params[:id])
end
def order_params
params.require(:order).permit(:arrival, :departure, :payment,
order_bikes_attributes: [:id, :bike_id, :bike_quantity, :_destroy,
bikes_attributes: [:id,:name, :bike_type_id,
bike_types_attributes: [:id, :name]]])
end
end
Просмотров / Order / _form
<%= simple_form_for [@bike_store, @order] do |f|%>
<%= f.simple_fields_for :order_bikes do |order_bike| %>
<%= order_bike.simple_fields_for :bikes do |bike| %>
<%= bike.input :bike_type, collection: @bike_type_list, input_html:{
id: "bike_type"
}%>
<%= order_bike.association :bike, collection: @bikes, input_html:{
value: @bikes.object_id,
id: "dynamic-bikes"
} %>
<% end %>
<% end %>
<% end %>
<script >
// dynamic bikes for change category
$(document).on("change", "#bike_type", 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) {
var bikes = response["bikes"];
$("#dynamic-bikes").empty();
$("#dynamic-bikes").append('<option>Select bike</option>');
for(var i=0; i< bikes.length; i++){
$("#dynamic-bikes").append('<option value="' + bikes[i]["id"] + '">' + bikes[i]["name"] + '</option>');
}
}
});
});
// dynamic bikes for releading form (e.g. new)
$(document).ready(function(){
var bike_type = $("#bike_type").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) {
var bikes = response["bikes"];
$("#dynamic-bikes").empty();
$("#dynamic-bikes").append('<option>Select bike</option>');
for(var i=0; i< bikes.length; i++){
$("#dynamic-bikes").append('<option value="' + bikes[i]["id"] + '">' + bikes[i]["name"] + '</option>');
}
}
});
});
</script>