0

我目前拥有的是非常标准的代码集,其中所有子对象都可以仅在其父对象下列出。

客户.rb

class Customer < ApplicationRecord
  has_many :bookings, dependent: :delete_all
end

预订.rb

class Booking < ApplicationRecord
  belongs_to :customer
  has_many_attached :images
end

路线.rb

Rails.application.routes.draw do
  resources :customers do
    resources :bookings
  end
end

bookings_controller.rb

这是自动生成的。我只删除了评论和 json 相关的行。

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

我想列出所有父对象的所有子对象。

我想,我将不得不修改路线如下

路线.rb

Rails.application.routes.draw do
  root 'customers#index'

  resources :customers do
    resources :bookings
  end
  resources :bookings
end

我也需要修改bookings_controller.rb

  1. 通过注释掉该行before_action :set_customer,否则我会收到类似的错误Couldn't find Customer without an ID

  2. 而且我将不得不把@customer = Customer.find(params[:customer_id])所有方法都放在除了index. 这意味着我不会遵循 DRY 概念......

还有其他更好的方法来解决这个问题吗?

4

1 回答 1

1

在我看来,你的方法已经是最好的了,只需要正确地使用 Rails 助手来保持你的代码干燥。

通过注释掉 before_action :set_customer 行,否则我会得到一个错误,比如找不到没有 ID 的客户

我将不得不为除索引之外的所有方法添加@customer = Customer.find(params[:customer_id])。这意味着我不会遵循 DRY 概念......

不,你不必。

如果在其他任何地方都没有使用的index动作,customers/bookings_controller那么只需从控制器文件中删除该动作并在路由文件中指定相同的内容:

resources :customers do
  resources :bookings, except: :index
end

如果该index操作仍在其他地方使用,则可以使用except以下选项声明 Rails 回调,以指定set_customer将为除index.

before_action :set_customer, except: :index

更多关于 Rails 控制器回调选项的信息在这里

您可能要检查的其他要点:

  1. dependent: :delete_all. 这样,active_storage_attachments当您删除customer. bookings因为它会触发回调,当attached images这些预订保持不变时,只删除关联的。参考
  2. resources :bookings (last line of your route file). 如果您只有index控制器中的操作,您也应该在此处声明相同的操作resources :bookings, only: :index
于 2020-02-23T09:47:29.363 回答