如何列出所有父对象的所有子对象?
How to list all child objects for all parent objects?
我目前拥有的是一套非常标准的代码,其中所有子对象只能列在它们的父对象下。
customer.rb
class Customer < ApplicationRecord
has_many :bookings, dependent: :delete_all
end
booking.rb
class Booking < ApplicationRecord
belongs_to :customer
has_many_attached :images
end
routes.rb
Rails.application.routes.draw do
resources :customers do
resources :bookings
end
end
bookings_controller.rb
This has been automatically generated. I only removed comments and json
related lines.
class BookingsController < ApplicationController
before_action :set_customer
before_action :set_booking, only: %i[show edit update destroy]
def index
@bookings = Booking.all.with_attached_images
end
def show; end
def new
@booking = @customer.bookings.build
end
def edit; end
def create
@booking = @customer.bookings.build(booking_params)
respond_to do |format|
if @booking.save
format.html { redirect_to @customer, notice: 'Booking was successfully created.' }
else
format.html { render :new }
end
end
end
def update
respond_to do |format|
if @booking.update(booking_params)
format.html { redirect_to [@customer, @booking], notice: 'Booking was successfully updated.' }
else
format.html { render :edit }
end
end
end
def destroy
@booking.destroy
respond_to do |format|
format.html { redirect_to customer_bookings_url, notice: 'Booking was successfully destroyed.' }
end
end
private
def set_customer
@customer = Customer.find(params[:customer_id])
end
def set_booking
@booking = @customer.bookings.find(params[:id])
end
def booking_params
params.require(:booking).permit(:name, :category, :rooms, :wifi, :phone, :address, :description, :available, :check_in, :check_out, :customer_id, images: [])
end
end
我想列出所有父对象的所有子对象。
我想,我将不得不如下修改路线
routes.rb
Rails.application.routes.draw do
root 'customers#index'
resources :customers do
resources :bookings
end
resources :bookings
end
我还需要修改bookings_controller.rb
注释掉before_action :set_customer
行,否则我会得到类似Couldn't find Customer without an ID
的错误
我必须为除 index
之外的所有方法添加 @customer = Customer.find(params[:customer_id])
。这意味着我不会遵循 DRY 概念...
还有其他更好的方法来解决这个问题吗?
我认为你的方法已经是最好的了,只需要正确使用 Rails 助手来保持你的代码干燥。
By commenting out the line before_action :set_customer, otherwise I
will get an error like Couldn't find Customer without an ID
And I will have to put @customer = Customer.find(params[:customer_id])
for all methods except index. Which means I won't be following DRY
concept...
不,您不必这样做。
如果 customers/bookings_controller
的 index
操作未在其他任何地方使用,则只需从控制器文件中删除该操作并在路由文件中指定相同的操作:
resources :customers do
resources :bookings, except: :index
end
如果 index
动作仍在其他地方使用,那么 Rails 回调可以使用 except
选项声明如下,以指定 set_customer
将被调用除 index
.
之外的所有操作
before_action :set_customer, except: :index
有关 Rails 控制器回调选项的更多信息 here
您可能需要检查的其他要点:
dependent: :delete_all
。有了这个,当你删除 customer
时,你的数据库中将有孤立的 active_storage_attachments
记录。因为当保留这些预订的 attached images
不变时,它会触发仅删除关联的 bookings
的回调。 Reference
resources :bookings (last line of your route file)
。如果控制器中只有 index
操作,则应在此处声明与 resources :bookings, only: :index
相同的操作
我目前拥有的是一套非常标准的代码,其中所有子对象只能列在它们的父对象下。
customer.rb
class Customer < ApplicationRecord
has_many :bookings, dependent: :delete_all
end
booking.rb
class Booking < ApplicationRecord
belongs_to :customer
has_many_attached :images
end
routes.rb
Rails.application.routes.draw do
resources :customers do
resources :bookings
end
end
bookings_controller.rb
This has been automatically generated. I only removed comments and json related lines.
class BookingsController < ApplicationController
before_action :set_customer
before_action :set_booking, only: %i[show edit update destroy]
def index
@bookings = Booking.all.with_attached_images
end
def show; end
def new
@booking = @customer.bookings.build
end
def edit; end
def create
@booking = @customer.bookings.build(booking_params)
respond_to do |format|
if @booking.save
format.html { redirect_to @customer, notice: 'Booking was successfully created.' }
else
format.html { render :new }
end
end
end
def update
respond_to do |format|
if @booking.update(booking_params)
format.html { redirect_to [@customer, @booking], notice: 'Booking was successfully updated.' }
else
format.html { render :edit }
end
end
end
def destroy
@booking.destroy
respond_to do |format|
format.html { redirect_to customer_bookings_url, notice: 'Booking was successfully destroyed.' }
end
end
private
def set_customer
@customer = Customer.find(params[:customer_id])
end
def set_booking
@booking = @customer.bookings.find(params[:id])
end
def booking_params
params.require(:booking).permit(:name, :category, :rooms, :wifi, :phone, :address, :description, :available, :check_in, :check_out, :customer_id, images: [])
end
end
我想列出所有父对象的所有子对象。
我想,我将不得不如下修改路线
routes.rb
Rails.application.routes.draw do
root 'customers#index'
resources :customers do
resources :bookings
end
resources :bookings
end
我还需要修改bookings_controller.rb
注释掉
before_action :set_customer
行,否则我会得到类似Couldn't find Customer without an ID
的错误
我必须为除
index
之外的所有方法添加@customer = Customer.find(params[:customer_id])
。这意味着我不会遵循 DRY 概念...
还有其他更好的方法来解决这个问题吗?
我认为你的方法已经是最好的了,只需要正确使用 Rails 助手来保持你的代码干燥。
By commenting out the line before_action :set_customer, otherwise I will get an error like Couldn't find Customer without an ID
And I will have to put @customer = Customer.find(params[:customer_id]) for all methods except index. Which means I won't be following DRY concept...
不,您不必这样做。
如果 customers/bookings_controller
的 index
操作未在其他任何地方使用,则只需从控制器文件中删除该操作并在路由文件中指定相同的操作:
resources :customers do
resources :bookings, except: :index
end
如果 index
动作仍在其他地方使用,那么 Rails 回调可以使用 except
选项声明如下,以指定 set_customer
将被调用除 index
.
before_action :set_customer, except: :index
有关 Rails 控制器回调选项的更多信息 here
您可能需要检查的其他要点:
dependent: :delete_all
。有了这个,当你删除customer
时,你的数据库中将有孤立的active_storage_attachments
记录。因为当保留这些预订的attached images
不变时,它会触发仅删除关联的bookings
的回调。 Referenceresources :bookings (last line of your route file)
。如果控制器中只有index
操作,则应在此处声明与resources :bookings, only: :index
相同的操作