Rails报错:创建Invoice时出现ActiveModel::MissingAttributeError
创建Invoice时自动生成InvoiceAppCollection报缺失属性错误
ActiveModel::MissingAttributeError in InvoicesController#create
can't write unknown attributeapp_collection_id
创建Invoice时尝试自动生成InvoiceAppCollection,触发上述报错。查资料得知这类问题通常与模型关联有关,但我认为自身模型关联配置正确。生成InvoiceAppCollection的方法写在Invoice控制器中:
def create_invoice_app_collection InvoiceAppCollection.create( po_number: @invoice.po_number, app_collection: @invoice.app_collection ) end
相关代码
模型代码
class AppCollection < ApplicationRecord belongs_to :company acts_as_tenant(:company) has_many :invoice_app_collections has_many :invoices, through: :invoice_app_collections validates :name, uniqueness: true end class Invoice < ApplicationRecord belongs_to :company acts_as_tenant(:company) has_many :invoice_app_collections has_many :app_collections, through: :invoice_app_collections validates :expiration, on: [:create, :update, :save], :presence => true end class InvoiceAppCollection < ApplicationRecord belongs_to :app_collection belongs_to :invoice belongs_to :company acts_as_tenant(:company) accepts_nested_attributes_for :app_collection end
AppCollectionController代码
class AppCollectionsController < ApplicationController before_action :set_app_collection, only: %i[ show edit update destroy ] def index AppCollections = app_collection.all end def create @app_collection = app_collection.new(app_collection_params) respond_to do |format| if @app_collection.save format.html { redirect_to app_collection_url(@app_collection), notice: "App collection was successfully created." } format.json { render :show, status: :created, location: @app_collection } else format.html { render :new, status: :unprocessable_entity } format.json { render json: @app_collection.errors, status: :unprocessable_entity } end end end def update respond_to do |format| if @app_collection.update(app_collection_params) format.html { redirect_to app_collection_url(@app_collection), notice: "App collection was successfully updated." } format.json { render :show, status: :ok, location: @app_collection } else format.html { render :edit, status: :unprocessable_entity } format.json { render json: @app_collection.errors, status: :unprocessable_entity } end end end def destroy @app_collection.destroy respond_to do |format| format.html { redirect_to app_collections_url, notice: "app collection was successfully destroyed." } format.json { head :no_content } end end private def set_app_collection @app_collection = app_collection.find(params[:id]) end def app_collection_params params.require(:app_collection).permit(:app_collection_type_id, :name, :company_id) end end
InvoicesController代码
class InvoicesController < ApplicationController before_action :set_invoice, only: %i[ show edit update destroy ] prepend_before_action :set_tenant after_action :create_invoice_app_collection, only: [:create, :update] def new @invoice_app_collection = Invoice.new end def create @invoice = Invoice.new(invoice_params) respond_to do |format| if @invoice.save format.html { redirect_to invoice_url(@invoice), notice: "Invoice was successfully created." } format.json { render :show, status: :created, location: @invoice } else format.html { render :new, status: :unprocessable_entity } format.json { render json: @invoice.errors, status: :unprocessable_entity } end end end def update respond_to do |format| if @invoice.update(invoice_params) format.html { redirect_to invoice_url(@invoice), notice: "Invoice was successfully updated." } format.json { render :show, status: :ok, location: @invoice } else format.html { render :edit, status: :unprocessable_entity } format.json { render json: @invoice.errors, status: :unprocessable_entity } end end end private def set_invoice @invoice = Invoice.find(params[:id]) end def invoice_params params.require(:invoice).permit(:company_id, :po_number, :amount, :expiration, {:app_collection_id => []} ) end def create_invoice_app_collection InvoiceAppCollection.create( po_number: @invoice.po_number, app_collection: @invoice.app_collection ) end end
InvoiceAppCollectionsController代码
class InvoiceAppCollectionsController < ApplicationController before_action :set_invoice_app_collection, only: %i[ show edit update destroy ] prepend_before_action :set_tenant def new @invoice_app_collection = InvoiceAppCollection.new end private def set_invoice_app_collection @invoice_app_collection = InvoiceAppCollection.find(params[:id]) end def invoice_app_collection_params params.require(:invoice_app_collection).permit(:company_id, :po_number, {:app_collection => []} ) end end
发票表单中App Collection选择框代码
<div> <%= form.label :app_collection, style: "display: block" %> <label> Select multiple app collections by holding the command key </label> <%= form.select :app_collection, options_for_select(app_collection.all.map {|a| [a.name, a.name]}),{include_blank: false} , class:"form-select", multiple: true %> </div>
数据库Schema
create_table "app_collections", charset: "latin1", force: :cascade do |t| t.integer "app_collection_type_id" t.string "name" t.integer "company_id" t.datetime "created_at", null: false t.datetime "updated_at", null: false end create_table "invoice_app_collections", charset: "latin1", force: :cascade do |t| t.integer "company_id" t.string "po_number" t.string "app_collection" t.datetime "created_at", null: false t.datetime "updated_at", null: false end create_table "invoices", charset: "latin1", force: :cascade do |t| t.integer "company_id" t.string "po_number" t.decimal "amount", precision: 10 t.datetime "expiration" t.string "app_collection" t.datetime "created_at", null: false t.datetime "updated_at", null: false end
已尝试的解决方法
- 将参数设置为数组格式
- 开启模型嵌套属性
问题仍未解决,寻求指导。
内容的提问来源于stack exchange,提问作者purplebentleyeater
相关产品推荐
相关产品推荐

