在我的应用程序中,我有一个“预订”表和一个“额外”表。
这是一个多对多的关系。因此,我创建了一个名为“ additions”的中间表
我使用“ has_many:through”建立表之间的关系:
class Booking < ActiveRecord::Base
has_many :additions
has_many :extras, :through => :additions
class Extra < ActiveRecord::Base
has_many :additions
has_many :extras, :through => :additions
class Addition < ActiveRecord::Base
belongs_to :booking
belongs_to :extra
这似乎有效。我手动为一些现有预订添加了一些附加功能(通过在添加表中添加数字),并编写了代码,以便在单击以显示预订时,它会列出所有相关的附加功能。
现在,我需要这样做,以便在您进行预订时-“额外费用”被保存到中间(附加)表中。
我的预订表格页面上有复选框:
<%= f.label 'Extras:' %>
<%= f.collection_check_boxes :extra_ids, Extra.all, :id, :extra_info %>
但是显然,当用户单击保存时,选择就被放弃了。
我需要一些代码(在控制器中?)以将这些“附加”保存到“附加表”中?
有什么想法,因为我无法解决该怎么做?!
谢谢!
class BookingsController < ApplicationController
respond_to :html, :xml, :json
before_action :find_room
# before_action :find_extra
def index
@bookings = Booking.where("room_id = ? AND end_time >= ?", @room.id, Time.now).order(:start_time)
respond_with @bookings
end
def new
@booking = Booking.new(room_id: @room.id)
end
def create
@booking = Booking.new(params[:booking].permit(:room_id, :start_time, :length, :user_id))
@booking.room = @room
if @booking.save
redirect_to room_bookings_path(@room, method: :get)
else
render 'new'
end
end
def show
@booking = Booking.find(params[:id])
end
def destroy
@booking = Booking.find(params[:id]).destroy
if @booking.destroy
flash[:notice] = "Booking: #{@booking.start_time.strftime('%e %b %Y %H:%M%p')} to #{@booking.end_time.strftime('%e %b %Y %H:%M%p')} deleted"
redirect_to room_bookings_path(@room)
else
render 'index'
end
end
def edit
@booking = Booking.find(params[:id])
end
def update
@booking = Booking.find(params[:id])
# @booking.room = @room
if @booking.update(params[:booking].permit(:room_id, :start_time, :length, :user_id))
flash[:notice] = 'Your booking was updated succesfully'
if request.xhr?
render json: {status: :success}.to_json
else
redirect_to resource_bookings_path(@room)
end
else
render 'edit'
end
end
private
def save booking
if @booking.save
flash[:notice] = 'booking added'
redirect_to room_booking_path(@room, @booking)
else
render 'new'
end
end
def find_room
if params[:room_id]
@room = Room.find_by_id(params[:room_id])
end
end
# def find_extra
# if params[:extra_id]
# @extra = Extra.find_by_id(params[:extra_id])
# end
# end
# If resource not found redirect to root and flash error.
def resource_not_found
yield
rescue ActiveRecord::RecordNotFound
redirect_to root_url, :notice => "Booking not found."
end
def booking_params
params.require(:booking).permit(:user_id, :extra_id)
end
end
------------------------
class AdditionsController < ApplicationController
before_action :set_addition, only: [:show, :edit, :update, :destroy]
# GET /additions
def index
@additions = Addition.all
end
# GET /additions/1
def show
end
# GET /additions/new
def new
@addition = Addition.new
end
# GET /additions/1/edit
def edit
end
# POST /additions
def create
@addition = Addition.new(addition_params)
if @addition.save
redirect_to @addition, notice: 'Addition was successfully created.'
else
render :new
end
end
# PATCH/PUT /additions/1
def update
if @addition.update(addition_params)
redirect_to @addition, notice: 'Addition was successfully updated.'
else
render :edit
end
end
# DELETE /additions/1
def destroy
@addition.destroy
redirect_to additions_url, notice: 'Addition was successfully destroyed.'
end
private
# Use callbacks to share common setup or constraints between actions.
def set_addition
@addition = Addition.find(params[:id])
end
# Only allow a trusted parameter "white list" through.
def addition_params
params.require(:addition).permit(:booking_id, :extra_id, :extra_name)
end
end
--------------------------------------
# @author Stacey Rees <https://github.com/staceysmells>
class ExtrasController < ApplicationController
# @see def resource_not_found
around_filter :resource_not_found
before_action :set_extra, only: [:show, :edit, :update, :destroy]
def index
@extras = Extra.all
end
def show
end
def new
@extra = Extra.new
end
def edit
end
def create
@extra = Extra.new(extra_params)
if @extra.save
redirect_to @extra, notice: 'Extra was successfully created.'
else
render :new
end
end
def update
if @extra.update(extra_params)
redirect_to @extra, notice: 'Extra was successfully updated.'
else
render :edit
end
end
def destroy
@extra.destroy
redirect_to extras_url, notice: 'Extra was successfully destroyed.'
end
private
# Use callbacks to share common setup or constraints between actions.
def set_extra
@extra = Extra.find(params[:id])
end
# If resource not found redirect to root and flash error.
def resource_not_found
yield
rescue ActiveRecord::RecordNotFound
redirect_to root_url, :notice => "Room Category not found."
end
# Only allow a trusted parameter "white list" through.
def extra_params
params.require(:extra).permit(:extraimg, :name, :description, :quantity, :price, :extracat_id)
end
end
您在这里正在使用嵌套表单属性。这有点复杂,但这也是人们经常做的事情,因此有一些不错的资源可用。
我建议您看一下这篇文章:http : //www.sitepoint.com/complex-rails-forms-with-nested-attributes/
特别是,名为“更复杂的关系”的部分专门提供了一个示例,该示例使用嵌套属性使用来建立多对多关联has_many :through
。
关键片段(评论者已经指出)将accepts_nested_attributes_for :extras
在您的预订模型中,并且f.fields_for :extras
在视图中显示一个块。您还需要修改booking_params
方法以允许嵌套值。您可能会遇到一些很强的参数陷阱,因此您可能需要查看文档。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句