首页 > 解决方案 > form_with 复合主键问题

问题描述

我为模型创建了一个带有复合主键的脚手架:

> bin/rails generate scaffold WineItem wine:references vintage:string

class CreateWineItems < ActiveRecord::Migration[6.0]
  def change
    create_table(:wine_items, primary_key: [:wine_id, :vintage]) do |t|
      t.references :wine, null: false, foreign_key: true
      t.string :vintage

      t.timestamps
    end
  end
end

我一直在处理与那个 Rails 相关的问题Active Record does not support composite primary key.

例如

对于show解决方法:

路线:

get '/wine_items/:wine_id/vintage/:vintage', to: 'wine_items#show', as: 'wine_item'
http://localhost:3000/wine_items/3/vintage/2019

在控制器中:

  def show
    @wine_item = WineItem.where({ wine_id: params[:wine_id], vintage: params[:vintage]})
  end

在视图中:

<p>
  <strong>Wine:</strong>
  <%= @wine_item.first.wine_id %>
</p>

<p>
  <strong>Vintage:</strong>
  <%= @wine_item.first.vintage %>
</p>

一切都好,但对于edit

路线:

get '/wine_items/:wine_id/vintage/:vintage/edit', to: 'wine_items#edit', as: 'edit_wine_item'
http://localhost:3000/wine_items/3/vintage/2019/edit

在控制器中:

  def edit
    @wine_item = WineItem.where({ wine_id: params[:wine_id], vintage: params[:vintage]})
  end

edit.html.erb

<%= render 'form', wine_item: @wine_item.first %>

但是助手_form.html.erb中的错误:form_with

<%= form_with(model: wine_item, local: true) do |form| %>
No route matches {:action=>"show", :controller=>"wine_items", :format=>nil, :vintage=>"2019", :wine_id=>#<WineItem wine_id: 3, vintage: "2019", created_at: "2021-07-07 10:09:07", updated_at: "2021-07-07 10:09:07">}, possible unmatched constraints: [:wine_id]

我检查了路线:

        Prefix Verb   URI Pattern                                          Controller#Action
    wine_items GET    /wine_items(.:format)                                wine_items#index
               POST   /wine_items(.:format)                                wine_items#create
 new_wine_item GET    /wine_items/new(.:format)                            wine_items#new
edit_wine_item GET    /wine_items/:wine_id/vintage/:vintage/edit(.:format) wine_items#edit
     wine_item GET    /wine_items/:wine_id/vintage/:vintage(.:format)      wine_items#show
               PATCH  /wine_items/:wine_id/vintage/:vintage(.:format)      wine_items#update
               PUT    /wine_items/:wine_id/vintage/:vintage(.:format)      wine_items#update
               DELETE /wine_items/:wine_id/vintage/:vintage(.:format)      wine_items#destroy

提前感谢

标签: ruby-on-rails

解决方案


我想您错过了 update(put/patch) 路由定义,并且请记住,您可以通过辅助选项定义自定义url和表单,请在此处查看(form_with options 部分)method


推荐阅读