Ruby on rails 如何更新脚手架生成的MVC+;具有2的嵌套资源的路由属于rails中的关系

Ruby on rails 如何更新脚手架生成的MVC+;具有2的嵌套资源的路由属于rails中的关系,ruby-on-rails,model-view-controller,nested,resources,scaffold,Ruby On Rails,Model View Controller,Nested,Resources,Scaffold,我正在Rails中创建一个虚拟库,当我试图在嵌套资源上为基本CRUD创建视图时,遇到了错误。我最好的猜测是我没有在视图中正确地传递变量和/或我生成的控制器没有正确更新。或者模型本身未正确设置为使用外键。我遵循了本教程: 主要区别在于我的嵌套资源(checkout_log)有2个外键(user_id和book_id),而不是示例中的1个外键。也许这就是答案,我无法创建仅依赖2个外键中的1个的路由?e、 g.预订/1/结帐记录/1 当前错误是:(控制器第7行) 我仍在掌握活动记录,所以我尝试了很多

我正在Rails中创建一个虚拟库,当我试图在嵌套资源上为基本CRUD创建视图时,遇到了错误。我最好的猜测是我没有在视图中正确地传递变量和/或我生成的控制器没有正确更新。或者模型本身未正确设置为使用外键。我遵循了本教程:

主要区别在于我的嵌套资源(checkout_log)有2个外键(user_id和book_id),而不是示例中的1个外键。也许这就是答案,我无法创建仅依赖2个外键中的1个的路由?e、 g.预订/1/结帐记录/1

当前错误是:(控制器第7行)

我仍在掌握活动记录,所以我尝试了很多方法。索引应显示@book的所有签出日志,该日志应使用get\u book设置

任何帮助都将不胜感激,谢谢。如果我没有提供足够的信息,请告诉我

签出日志.rb

class CheckoutLog < ApplicationRecord
  belongs_to :user
  belongs_to :book
end

routes.rb(目前主要关注书籍和结帐日志)

签出日志控制器.rb

    class CheckoutLogsController < ApplicationController
  before_action :get_book, :set_checkout_log, only: [:show, :edit, :update, :destroy]

  # GET /checkout_logs
  # GET /checkout_logs.json
  def index
    @checkout_logs = @book.checkout_logs
  end

  # GET /checkout_logs/1
  # GET /checkout_logs/1.json
  def show    
  end

  # GET /checkout_logs/new
  def new
    @checkout_log = @book.checkout_logs.build
  end

  # GET /checkout_logs/1/edit
  def edit
  end

  # POST /checkout_logs
  # POST /checkout_logs.json
  def create
    @checkout_log = CheckoutLog.new(checkout_log_params)

    respond_to do |format|
      if @checkout_log.save
        format.html { redirect_to @checkout_log, notice: 'Checkout log was successfully created.' }
        format.json { render :show, status: :created, location: @checkout_log }
      else
        format.html { render :new }
        format.json { render json: @checkout_log.errors, status: :unprocessable_entity }
      end
    end
  end

  # PATCH/PUT /checkout_logs/1
  # PATCH/PUT /checkout_logs/1.json
  def update
    respond_to do |format|
      if @checkout_log.update(checkout_log_params)
        format.html { redirect_to @checkout_log, notice: 'Checkout log was successfully updated.' }
        format.json { render :show, status: :ok, location: @checkout_log }
      else
        format.html { render :edit }
        format.json { render json: @checkout_log.errors, status: :unprocessable_entity }
      end
    end
  end

  # DELETE /checkout_logs/1
  # DELETE /checkout_logs/1.json
  def destroy
    @checkout_log.destroy
    respond_to do |format|
      format.html { redirect_to checkout_logs_url, notice: 'Checkout log was successfully destroyed.' }
      format.json { head :no_content }
    end
  end

  private
    #get book associated with this checkout_log
    def get_book
      @book = Book.find(params[:book_id])
    end

    # Use callbacks to share common setup or constraints between actions.
    def set_checkout_log
      @checkout_log = @book.checkout_logs.find(params[:id])      
    end

    # Only allow a list of trusted parameters through.
    def checkout_log_params
      params.require(:checkout_log).permit(:checkout_date, :due_date, :returned_date, :user_id, :book_id)
    end
end
类签出日志控制器
index.html.erb(签出日志索引)

签出日志 使用者 书 结帐日期 到期日 返回者
_form.html.erb(checkout\u log form partial,我只更改了第一行以添加book)


禁止保存此签出日志:

在签出日志\u控制器中,我需要在两个单独的行上执行before\u操作。我想出于某种原因,我可以把它们列在一个清单上

 before_action :get_book
 before_action :set_checkout_log, only: [:show, :edit, :update, :destroy]

在checkout\u logs\u控制器中,我需要在两条单独的行上执行before\u操作。我想出于某种原因,我可以把它们列在一个清单上

 before_action :get_book
 before_action :set_checkout_log, only: [:show, :edit, :update, :destroy]
ActiveRecord::Schema.define(version: 2020_12_30_171415) do

  # These are extensions that must be enabled in order to support this database
  enable_extension "plpgsql"

  create_table "books", force: :cascade do |t|
    t.string "title"
    t.string "author"
    t.string "genre"
    t.string "subgenre"
    t.integer "pages"
    t.string "publisher"
    t.datetime "created_at", precision: 6, null: false
    t.datetime "updated_at", precision: 6, null: false
    t.integer "book_number"
  end

  create_table "checkout_logs", force: :cascade do |t|
    t.datetime "checkout_date"
    t.datetime "due_date"
    t.datetime "returned_date"
    t.bigint "user_id", null: false
    t.bigint "book_id", null: false
    t.datetime "created_at", precision: 6, null: false
    t.datetime "updated_at", precision: 6, null: false
    t.index ["book_id"], name: "index_checkout_logs_on_book_id"
    t.index ["user_id"], name: "index_checkout_logs_on_user_id"
  end

  create_table "users", force: :cascade do |t|
    t.string "email", default: "", null: false
    t.string "encrypted_password", default: "", null: false
    t.string "reset_password_token"
    t.datetime "reset_password_sent_at"
    t.datetime "remember_created_at"
    t.datetime "created_at", precision: 6, null: false
    t.datetime "updated_at", precision: 6, null: false
    t.boolean "admin", default: false
    t.index ["email"], name: "index_users_on_email", unique: true
    t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true
  end

  add_foreign_key "checkout_logs", "books"
  add_foreign_key "checkout_logs", "users"
end

Rails.application.routes.draw do    
  devise_for :users
  
  get 'my_books/index'
  get 'my_books/borrow'
  get 'my_books/return'
  get 'books/listing'
  get 'books/borrow'
  
  get 'home/index'
  
  resources :books do    
    resources :checkout_logs
  end

  root to: "home#index"
  # For details on the DSL available within this file, see https://guides.rubyonrails.org/routing.html
end

    class CheckoutLogsController < ApplicationController
  before_action :get_book, :set_checkout_log, only: [:show, :edit, :update, :destroy]

  # GET /checkout_logs
  # GET /checkout_logs.json
  def index
    @checkout_logs = @book.checkout_logs
  end

  # GET /checkout_logs/1
  # GET /checkout_logs/1.json
  def show    
  end

  # GET /checkout_logs/new
  def new
    @checkout_log = @book.checkout_logs.build
  end

  # GET /checkout_logs/1/edit
  def edit
  end

  # POST /checkout_logs
  # POST /checkout_logs.json
  def create
    @checkout_log = CheckoutLog.new(checkout_log_params)

    respond_to do |format|
      if @checkout_log.save
        format.html { redirect_to @checkout_log, notice: 'Checkout log was successfully created.' }
        format.json { render :show, status: :created, location: @checkout_log }
      else
        format.html { render :new }
        format.json { render json: @checkout_log.errors, status: :unprocessable_entity }
      end
    end
  end

  # PATCH/PUT /checkout_logs/1
  # PATCH/PUT /checkout_logs/1.json
  def update
    respond_to do |format|
      if @checkout_log.update(checkout_log_params)
        format.html { redirect_to @checkout_log, notice: 'Checkout log was successfully updated.' }
        format.json { render :show, status: :ok, location: @checkout_log }
      else
        format.html { render :edit }
        format.json { render json: @checkout_log.errors, status: :unprocessable_entity }
      end
    end
  end

  # DELETE /checkout_logs/1
  # DELETE /checkout_logs/1.json
  def destroy
    @checkout_log.destroy
    respond_to do |format|
      format.html { redirect_to checkout_logs_url, notice: 'Checkout log was successfully destroyed.' }
      format.json { head :no_content }
    end
  end

  private
    #get book associated with this checkout_log
    def get_book
      @book = Book.find(params[:book_id])
    end

    # Use callbacks to share common setup or constraints between actions.
    def set_checkout_log
      @checkout_log = @book.checkout_logs.find(params[:id])      
    end

    # Only allow a list of trusted parameters through.
    def checkout_log_params
      params.require(:checkout_log).permit(:checkout_date, :due_date, :returned_date, :user_id, :book_id)
    end
end
<p id="notice"><%= notice %></p>

<h1>Checkout Logs</h1>

<table>
  <thead>
    <tr>
      <th>User</th>
      <th>Book</th>
      <th>CheckoutDate</th>
      <th>DueDate</th>
      <th>ReturnedDate</th>      
      <th colspan="3"></th>
    </tr>
  </thead>

  <tbody>
    <% Array(@checkout_logs).each do |checkout_log| %>
      <tr>
        <td><%= checkout_log.user_id %></td>
        <td><%= checkout_log.book_id %></td>
        <td><%= checkout_log.checkout_date %></td>
        <td><%= checkout_log.due_date %></td>
        <td><%= checkout_log.returned_date %></td>        
        <td><%= link_to 'Show', book_checkout_log_path(checkout_log) %></td>
        <td><%= link_to 'Edit', edit_book_checkout_log_path(checkout_log) %></td>
        <td><%= link_to 'Destroy', book_checkout_log_path(checkout_log), method: :delete, data: { confirm: 'Are you sure?' } %></td>
      </tr>
    <% end %>
  </tbody>
</table>

<br>

<%= link_to 'New Checkout Log', new_book_checkout_log_path %>

<%= link_to 'Back', books_path %>

<%= form_with(model: [@book, @checkout_log], local: true) do |form| %>
  <% if checkout_log.errors.any? %>
    <div id="error_explanation">
      <h2><%= pluralize(checkout_log.errors.count, "error") %> prohibited this checkout_log from being saved:</h2>

      <ul>
        <% checkout_log.errors.full_messages.each do |message| %>
          <li><%= message %></li>
        <% end %>
      </ul>
    </div>
  <% end %>

  <div class="field">
    <%= form.label :UserId %>
    <%= form.number_field :UserId %>
  </div>

  <div class="field">
    <%= form.label :BookId %>
    <%= form.number_field :BookId %>
  </div>

  <div class="field">
    <%= form.label :checkout_date %>
    <%= form.datetime_select :checkout_date %>
  </div>

  <div class="field">
    <%= form.label :due_date %>
    <%= form.datetime_select :due_date %>
  </div>

  <div class="field">
    <%= form.label :returned_date %>
    <%= form.datetime_select :returned_date %>
  </div>

  <div class="field">
    <%= form.label :user_id %>
    <%= form.text_field :user_id %>
  </div>

  <div class="field">
    <%= form.label :book_id %>
    <%= form.text_field :book_id %>
  </div>

  <div class="actions">
    <%= form.submit %>
  </div>
<% end %>

 before_action :get_book
 before_action :set_checkout_log, only: [:show, :edit, :update, :destroy]