嗨,我是ruby on rails的新手。我创造了两个型号的品牌和产品。一个品牌可以与许多产品相关。我使用脚手架,因为这是我们的讲师希望我们在项目中做的事情。
我尝试设置我的产品屏幕,这样当您输入产品时,您会看到一个品牌名称下拉列表供您选择。输入产品详细信息时,选择品牌名称,然后单击“提交”;所选波段名称中的brand_id保存在product.brand_id表中。 (我相信当我在控制器中设置has_many时,会在products表中自动创建brand_id)。
我尝试过使用collection_set但是我正在努力奋斗。我尝试过使用堆栈溢出的一些技巧,但没有一个工作,作为最后的手段我尝试自己发一个帖子。
在模型中我添加了以下内容:
class Brand < ApplicationRecord
has_many :product
validates :brand_name, presence: true
end
class Product < ApplicationRecord
belongs_to :brand
validates :name, presence: true
end
根据我的理解,这意味着产品表将具有brand_id和id。
在产品控制器中,我添加了以下内容:
class ProductsController < ApplicationController
before_action :set_product, only: [:show, :edit, :update, :destroy]
# GET /products
# GET /products.json
def index
@products = Product.all
end
# GET /products/1
# GET /products/1.json
def show
end
# GET /products/new
def new
@brand = Brand.all
@product = Product.new
end
... more code ...
在产品视图的表单中,我添加了以下内容
<%= form_for(product) do |f| %>
<% if product.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(product.errors.count, "error") %> prohibited this product from being saved:</h2>
<ul>
<% product.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :name %>
<%= f.text_field :name %>
</div>
<div class="field">
<%= f.label :model %>
<%= f.text_field :model %>
</div>
<div class="field">
<%= f.label :price %>
<%= f.text_field :price %>
</div>
<div class="field">
<%= f.label :vat %>
<%= f.text_field :vat %>
</div>
<div class="field">
<%= f.label :image_uri %>
<%= f.text_field :image_uri %>
</div>
<div class="field">
<%= f.collection_select :brand_id, @brand, :id, :brand_name %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
的routes.rb
Rails.application.routes.draw do
resources :users
resources :products
resources :sales_orders
resources :payments
resources :filter_group_items
resources :filter_groups
resources :categories
resources :sales_order_lines
resources :brands
resources :addresses
get '/cart' => 'cart#index'
get '/products' => 'products#index'
get '/brands' => 'brands#index'
get '/users' => 'users#index'
get '/addresses' => 'addresses#index'
get '/payments' => 'payments#index'
# For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
#root 'application#hello'
# You can have the root of your site routed with "root"
#root 'welcome#index'
root 'products#index'
end
我收到以下错误 显示/home/ubuntu/workspace/ssd_project/app/views/products/_form.html.erb,其中第40行被提出:
未定义的方法`brand_id'代表# 你的意思是?品牌
39 <div class="field">
40 <%= f.collection_select :brand_id, @brand, :id, :brand_name %>
41 </div>
模板包含跟踪:app / views / products / new.html.erb
如果有人对如何做到这一点有任何建议,我将非常感激。
New Routes.rb
Rails.application.routes.draw do
resources :users
resources :products
resources :sales_orders
resources :payments
resources :filter_group_items
resources :filter_groups
resources :categories
resources :sales_order_lines
resources :brands
resources :addresses
resources :brands do
resources :products
end
get '/cart' => 'cart#index'
get '/products' => 'products#new'
get '/brands' => 'brands#index'
get '/users' => 'users#index'
get '/addresses' => 'addresses#index'
get '/payments' => 'payments#index'
# For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
#root 'application#hello'
# You can have the root of your site routed with "root"
#root 'welcome#index'
root 'products#index'
end
Database Schema schema.rb
# This file is auto-generated from the current state of the database. Instead
# of editing this file, please use the migrations feature of Active Record to
# incrementally modify your database, and then regenerate this schema definition.
#
# Note that this schema.rb definition is the authoritative source for your
# database schema. If you need to create the application database on another
# system, you should be using db:schema:load, not running all the migrations
# from scratch. The latter is a flawed and unsustainable approach (the more migrations
# you'll amass, the slower it'll run and the greater likelihood for issues).
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 20160706122948) do
create_table "addresses", force: :cascade do |t|
t.string "line1"
t.string "line2"
t.string "line3"
t.string "country"
t.string "post_code"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "brands", force: :cascade do |t|
t.string "brand_name"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "categories", force: :cascade do |t|
t.string "name"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "filter_group_items", force: :cascade do |t|
t.string "description"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "filter_groups", force: :cascade do |t|
t.string "description"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "payments", force: :cascade do |t|
t.datetime "date"
t.decimal "amount"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "products", force: :cascade do |t|
t.string "name"
t.string "model"
t.decimal "price"
t.decimal "vat"
t.string "image_uri"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "sales_order_lines", force: :cascade do |t|
t.integer "qty"
t.decimal "price"
t.decimal "total"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "sales_orders", force: :cascade do |t|
t.datetime "date"
t.decimal "total"
t.decimal "vat"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "users", force: :cascade do |t|
t.string "name"
t.string "email"
t.string "password"
t.string "phone"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.boolean "admin_user", default: false
end
end
答案 0 :(得分:1)
<div class="field">
<%= f.collection_select :brand_id, Brand.all, :id, :brand_name %>
</div>
第二个参数是一个集合,您可以使用Brand.all
然后,您可以在新操作
下取出Products控制器中的行@brand = Brand.all
此外,在您的表单中,我认为您应该有form_for(@product)而不是产品。您需要实例变量@product
您的路线是否已安排,以便产品嵌套在品牌下?看看路线也会很有帮助。这是另一个潜在的问题
<强>编辑:强>
这将是嵌套路线(您的应用没有)的示例:
resources :brands do
resources :products
end
这会产生这样的路线:
/品牌/:brand_id /产品/:ID
所以我重新创建了你的应用,发现form_for(product)
对我造成了错误。如果它切换到@product
,一个实例变量(您已在控制器中设置),那么您的代码按预期工作。 form_for(@product)
应与产品控制器中的@product = Product.new
匹配,即新操作。回顾过去,我关于如何进行collection.select的其他建议本质上更具风格,但我相信它使您的代码更容易理解。
第二次编辑:
您的schema.rb文件显示了该问题。您的产品表中不包含对品牌表的引用,即使您已将两者与模型中的has_many
和belongs_to
相关联(与您认为不会自动发生的情况相反,但而是通过数据库迁移)。关键是,产品表缺少brand_id
列
首先,我会删除你的路线,以便它像以前一样:
resources :products
resources :brands
然后,您需要运行迁移以将品牌引用添加到products表。在命令行中,使用命令rails generate migration add_reference_to_products
,然后在迁移文件夹(可在/ db / migrate中找到)中打开刚刚创建的迁移文件。将以下内容添加到def change
块中:
def change
add_reference :products, :brand, index: true, foreign_key: true
end
确保保存文件。然后在命令行中键入rake db:migrate
以运行迁移。这将在您的product表中为brand_id
创建一列,您的代码应该可以使用