NoMethodError Rails 4 App -> 嵌套属性问题
NoMethodError Rails 4 App -> Nested attribute issue
我正在开发一个 Rails 4 应用程序,我的模块之一是一般巡逻报告,其中用户根据他/她的轮班开始/停止创建报告。创建报告后,他们可以选择返回报告视图并添加巡逻报告。
在 gen_rep_ent 表单提交之前,一切都在进行中。
我得到的具体错误是:
undefined method `general_report=' for #<GenRepEnt:0x007f871d9ea150>
其次是:
def create
@general_report = GeneralReport.find(params[:general_report_id])
@gen_rep_ent = GenRepEnt.new(gen_rep_ent_params)
@gen_rep_ent.general_report = @gen_rep_ent <-- Problem Line
respond_to do |format|
if @gen_rep_ent.save
format.html { redirect_to @general_report, notice: 'General Report Entry was successfully created.' }
format.json { render :show, status: :created, location: @general_report}
else
format.html { render :new }
format.json { render json: @general_report.errors, status: :unprocessable_entity }
end
end
end
这是导致此处问题的第 3 行。
我的general_report模型有如下关系:
has_many :gen_rep_ents, dependent: :destroy
我的路线文件看起来像:
Rails.application.routes.draw do
resources :mobile_alarm_reports
resources :mobile_incident_reports
resources :static_incident_reports
resources :general_reports do
resources :gen_rep_ents, except: [:index], controller: 'general_reports/gen_rep_ents'
end
resources :visitor_parkings
resources :residents
resources :sites
devise_for :users, controllers: { registrations: "registrations" }
# Adds Static Pages
root 'home#index'
get 'home/about'
get 'home/contact'
get 'home/pricing'
我的节目文件看起来像:
<% @gen_rep_ents.each do |gen_rep_ent| %>
<table>
<thead>
<tr>
<th>Time</th>
<th>Report</th>
</tr>
</thead>
<tbody>
<tr>
<td><%= gen_rep_ent.time %></td>
<td><%= gen_rep_ent.report %></td>
</tr>
</tbody>
<% end %>
</table>
gen_rep_ents_controller.rb: <-- 嵌套项
class GeneralReports::GenRepEntsController < ApplicationController
before_action :set_gen_rep_ent, only: [:show, :edit, :update, :destroy]
# GET /gen_rep_ents
# GET /gen_rep_ents.json
def index
@gen_rep_ents = GenRepEnt.all
end
# GET /gen_rep_ents/1
# GET /gen_rep_ents/1.json
def show
end
# GET /gen_rep_ents/new
def new
@general_report = GeneralReport.find(params[:general_report_id])
@gen_rep_ent = GenRepEnt.new
end
# GET /gen_rep_ents/1/edit
def edit
end
# POST /gen_rep_ents
# POST /gen_rep_ents.json
def create
@general_report = GeneralReport.find(params[:general_report_id])
@gen_rep_ent = GenRepEnt.new(gen_rep_ent_params)
@gen_rep_ent.general_report = @gen_rep_ent
respond_to do |format|
if @gen_rep_ent.save
format.html { redirect_to @general_report, notice: 'General Report Entry was successfully created.' }
format.json { render :show, status: :created, location: @general_report}
else
format.html { render :new }
format.json { render json: @general_report.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /gen_rep_ents/1
# PATCH/PUT /gen_rep_ents/1.json
def update
respond_to do |format|
if @gen_rep_ent.update(gen_rep_ent_params)
format.html { redirect_to @gen_rep_ent, notice: 'General Report Entry was successfully updated.' }
format.json { render :show, status: :ok, location: @gen_rep_ent }
else
format.html { render :edit }
format.json { render json: @gen_rep_ent.errors, status: :unprocessable_entity }
end
end
end
# DELETE /gen_rep_ents/1
# DELETE /gen_rep_ents/1.json
def destroy
@gen_rep_ent.destroy
respond_to do |format|
format.html { redirect_to gen_rep_ents_url, notice: 'General Report Entry was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_gen_rep_ent
@gen_rep_ent = GenRepEnt.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def gen_rep_ent_params
params.require(:gen_rep_ent).permit(:time, :report, :general_report)
end
end
general_reports_controller:<-- 父项
class GeneralReportsController < ApplicationController
before_action :set_general_report, only: [:show, :edit, :update, :destroy]
# GET /general_reports
# GET /general_reports.json
def index
@general_reports = GeneralReport.all
end
# GET /general_reports/1
# GET /general_reports/1.json
def show
@general_report = GeneralReport.find(params[:id])
@gen_rep_ents = @general_report.gen_rep_ents
end
# GET /general_reports/new
def new
@general_report = GeneralReport.new
end
# GET /general_reports/1/edit
def edit
end
# POST /general_reports
# POST /general_reports.json
def create
@general_report = GeneralReport.new(general_report_params)
respond_to do |format|
if @general_report.save
format.html { redirect_to @general_report, notice: 'General report was successfully created.' }
format.json { render :show, status: :created, location: @general_report }
else
format.html { render :new }
format.json { render json: @general_report.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /general_reports/1
# PATCH/PUT /general_reports/1.json
def update
respond_to do |format|
if @general_report.update(general_report_params)
format.html { redirect_to @general_report, notice: 'General report was successfully updated.' }
format.json { render :show, status: :ok, location: @general_report }
else
format.html { render :edit }
format.json { render json: @general_report.errors, status: :unprocessable_entity }
end
end
end
# DELETE /general_reports/1
# DELETE /general_reports/1.json
def destroy
@general_report.destroy
respond_to do |format|
format.html { redirect_to general_reports_url, notice: 'General report was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_general_report
@general_report = GeneralReport.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def general_report_params
params.require(:general_report).permit(:user_id, :site_id, :date, :shift_start, :shift_end, :gp_number)
end
end
我不太确定哪里出了问题,因为我已经一遍又一遍地查看了教程,它与我所看到的完全匹配。
编辑#1
我的 GenRepEnt 模型看起来像:
class GenRepEnt < ActiveRecord::Base
belongs_to :general_report
end
编辑 # 2
执行迁移并将 belongs_to :general_report 添加到模型后,出现以下错误:
ActiveRecord::AssociationTypeMismatch in
GeneralReports::GenRepEntsController#create
看起来您正在尝试在 GenRepEnt
class 的实例上设置 general_report
,但该方法不存在。这可能是因为未在 GenRepEnt
模型中建立关联。
在模型 gen_rep_ent.rb
中添加以下关联:
belongs_to :general_report
声明此关联后 Rails 将在 GenRepEnt
的每个实例上定义一些方法,包括:
general_report
general_report=
您还需要生成一个迁移,将新列 general_report_id
添加到 gen_rep_ents
table.
在您的终端中 运行 rails g migration AddGeneralReportRefToGenRepEnts general_report:references
这应该生成如下所示的迁移:
class AddGeneralReportRefToGenRepEnts < ActiveRecord::Migration
def change
add_reference :gen_rep_ents, :general_report, index: true, foreign_key: true
end
end
接下来,运行 使用 rake db:migrate
进行迁移并重新启动您的应用。
阅读有关 belongs_to 协会的更多信息 here。
我正在开发一个 Rails 4 应用程序,我的模块之一是一般巡逻报告,其中用户根据他/她的轮班开始/停止创建报告。创建报告后,他们可以选择返回报告视图并添加巡逻报告。
在 gen_rep_ent 表单提交之前,一切都在进行中。
我得到的具体错误是:
undefined method `general_report=' for #<GenRepEnt:0x007f871d9ea150>
其次是:
def create
@general_report = GeneralReport.find(params[:general_report_id])
@gen_rep_ent = GenRepEnt.new(gen_rep_ent_params)
@gen_rep_ent.general_report = @gen_rep_ent <-- Problem Line
respond_to do |format|
if @gen_rep_ent.save
format.html { redirect_to @general_report, notice: 'General Report Entry was successfully created.' }
format.json { render :show, status: :created, location: @general_report}
else
format.html { render :new }
format.json { render json: @general_report.errors, status: :unprocessable_entity }
end
end
end
这是导致此处问题的第 3 行。
我的general_report模型有如下关系:
has_many :gen_rep_ents, dependent: :destroy
我的路线文件看起来像:
Rails.application.routes.draw do
resources :mobile_alarm_reports
resources :mobile_incident_reports
resources :static_incident_reports
resources :general_reports do
resources :gen_rep_ents, except: [:index], controller: 'general_reports/gen_rep_ents'
end
resources :visitor_parkings
resources :residents
resources :sites
devise_for :users, controllers: { registrations: "registrations" }
# Adds Static Pages
root 'home#index'
get 'home/about'
get 'home/contact'
get 'home/pricing'
我的节目文件看起来像:
<% @gen_rep_ents.each do |gen_rep_ent| %>
<table>
<thead>
<tr>
<th>Time</th>
<th>Report</th>
</tr>
</thead>
<tbody>
<tr>
<td><%= gen_rep_ent.time %></td>
<td><%= gen_rep_ent.report %></td>
</tr>
</tbody>
<% end %>
</table>
gen_rep_ents_controller.rb: <-- 嵌套项
class GeneralReports::GenRepEntsController < ApplicationController
before_action :set_gen_rep_ent, only: [:show, :edit, :update, :destroy]
# GET /gen_rep_ents
# GET /gen_rep_ents.json
def index
@gen_rep_ents = GenRepEnt.all
end
# GET /gen_rep_ents/1
# GET /gen_rep_ents/1.json
def show
end
# GET /gen_rep_ents/new
def new
@general_report = GeneralReport.find(params[:general_report_id])
@gen_rep_ent = GenRepEnt.new
end
# GET /gen_rep_ents/1/edit
def edit
end
# POST /gen_rep_ents
# POST /gen_rep_ents.json
def create
@general_report = GeneralReport.find(params[:general_report_id])
@gen_rep_ent = GenRepEnt.new(gen_rep_ent_params)
@gen_rep_ent.general_report = @gen_rep_ent
respond_to do |format|
if @gen_rep_ent.save
format.html { redirect_to @general_report, notice: 'General Report Entry was successfully created.' }
format.json { render :show, status: :created, location: @general_report}
else
format.html { render :new }
format.json { render json: @general_report.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /gen_rep_ents/1
# PATCH/PUT /gen_rep_ents/1.json
def update
respond_to do |format|
if @gen_rep_ent.update(gen_rep_ent_params)
format.html { redirect_to @gen_rep_ent, notice: 'General Report Entry was successfully updated.' }
format.json { render :show, status: :ok, location: @gen_rep_ent }
else
format.html { render :edit }
format.json { render json: @gen_rep_ent.errors, status: :unprocessable_entity }
end
end
end
# DELETE /gen_rep_ents/1
# DELETE /gen_rep_ents/1.json
def destroy
@gen_rep_ent.destroy
respond_to do |format|
format.html { redirect_to gen_rep_ents_url, notice: 'General Report Entry was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_gen_rep_ent
@gen_rep_ent = GenRepEnt.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def gen_rep_ent_params
params.require(:gen_rep_ent).permit(:time, :report, :general_report)
end
end
general_reports_controller:<-- 父项
class GeneralReportsController < ApplicationController
before_action :set_general_report, only: [:show, :edit, :update, :destroy]
# GET /general_reports
# GET /general_reports.json
def index
@general_reports = GeneralReport.all
end
# GET /general_reports/1
# GET /general_reports/1.json
def show
@general_report = GeneralReport.find(params[:id])
@gen_rep_ents = @general_report.gen_rep_ents
end
# GET /general_reports/new
def new
@general_report = GeneralReport.new
end
# GET /general_reports/1/edit
def edit
end
# POST /general_reports
# POST /general_reports.json
def create
@general_report = GeneralReport.new(general_report_params)
respond_to do |format|
if @general_report.save
format.html { redirect_to @general_report, notice: 'General report was successfully created.' }
format.json { render :show, status: :created, location: @general_report }
else
format.html { render :new }
format.json { render json: @general_report.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /general_reports/1
# PATCH/PUT /general_reports/1.json
def update
respond_to do |format|
if @general_report.update(general_report_params)
format.html { redirect_to @general_report, notice: 'General report was successfully updated.' }
format.json { render :show, status: :ok, location: @general_report }
else
format.html { render :edit }
format.json { render json: @general_report.errors, status: :unprocessable_entity }
end
end
end
# DELETE /general_reports/1
# DELETE /general_reports/1.json
def destroy
@general_report.destroy
respond_to do |format|
format.html { redirect_to general_reports_url, notice: 'General report was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_general_report
@general_report = GeneralReport.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def general_report_params
params.require(:general_report).permit(:user_id, :site_id, :date, :shift_start, :shift_end, :gp_number)
end
end
我不太确定哪里出了问题,因为我已经一遍又一遍地查看了教程,它与我所看到的完全匹配。
编辑#1
我的 GenRepEnt 模型看起来像:
class GenRepEnt < ActiveRecord::Base
belongs_to :general_report
end
编辑 # 2
执行迁移并将 belongs_to :general_report 添加到模型后,出现以下错误:
ActiveRecord::AssociationTypeMismatch in GeneralReports::GenRepEntsController#create
看起来您正在尝试在 GenRepEnt
class 的实例上设置 general_report
,但该方法不存在。这可能是因为未在 GenRepEnt
模型中建立关联。
在模型 gen_rep_ent.rb
中添加以下关联:
belongs_to :general_report
声明此关联后 Rails 将在 GenRepEnt
的每个实例上定义一些方法,包括:
general_report
general_report=
您还需要生成一个迁移,将新列 general_report_id
添加到 gen_rep_ents
table.
在您的终端中 运行 rails g migration AddGeneralReportRefToGenRepEnts general_report:references
这应该生成如下所示的迁移:
class AddGeneralReportRefToGenRepEnts < ActiveRecord::Migration
def change
add_reference :gen_rep_ents, :general_report, index: true, foreign_key: true
end
end
接下来,运行 使用 rake db:migrate
进行迁移并重新启动您的应用。
阅读有关 belongs_to 协会的更多信息 here。