【问题标题】:Ruby Rails - NoMethodError , drop-down listRuby Rails - NoMethodError ,下拉列表
【发布时间】:2014-05-12 20:47:46
【问题描述】:

我正在尝试关注this tutorial。它写在以前版本的 Rails 中,我使用的是 Rails 4。有一个下拉列表选择不出现,我收到以下错误:

NoMethodError in Book#show
Showing C:/Ruby193/mylibrary/app/views/book/show.html where line #3 raised:

undefined method `name' for nil:NilClass
Extracted source (around line #3):

 1 <h1><%= @book.title %></h1>
 2 <p><strong>Price: </strong> $<%= @book.price %><br />
 3 <strong>Subject: </strong> <%= @subject.name %><br />
 4 </p>
 5 <p><%= @book.description %></p>
 6 <hr />

Rails.root: C:/Ruby193/mylibrary

这里是show.html

  <h1><%= @book.title %></h1>
    <p><strong>Price: </strong> $<%= @book.price %><br />
    <strong>Subject: </strong> <%= @book.subject.name %><br />
    </p>
    <p><%= @book.description %></p>
    <hr />
    <%= link_to 'Back', {:action => 'list'} %>

这里是 migrate/258412_subjects.rb

class Subjects < ActiveRecord::Migration
  def self.up
      create_table :subjects do |t|
       t.column :name, :string
    end
    Subject.create :name => "Physics"
    Subject.create :name => "Mathematics"
    Subject.create :name => "Chemistry"
    Subject.create :name => "Psychology"
    Subject.create :name => "Geography"
  end

  def self.down
      drop_table :subjects
  end
end

这里是 migrate/05465_books.rb

class Books < ActiveRecord::Migration
  def self.up
     create_table :books do |t|
    t.column :title, :string, :limit => 32, :null => false
    t.column :price, :float
    t.column :subject_id, :integer
    t.column :description, :text
     end
  end

  def self.down
    drop_table :books
  end
end

这里是models/book.rb

class Book < ActiveRecord::Base
    belongs_to :subject
    validates_presence_of :title
    validates_numericality_of :price, :message=>"Error Message"
end

这是我的控制器类 book_controller.rb

class BookController < ApplicationController

  def list
    @books = Book.all
  end
  def show
    @book = Book.find(params[:id])
  end
  def new
    @book = Book.new
    @subjects = Subject.all
  end
  def create
    @book = Book.new(book_params)
    if @book.save!
      redirect_to :action => 'list'
    else
      @subjects = Subject.all
      render :action => 'new'
    end
  end
  def edit
    @book = Book.find(params[:id])
    @subjects = Subject.all
  end
  def update
    @book = Book.find(params[:id])
    if @book.update_attributes(book_params)
      redirect_to :action => 'show', :id => @book
    else
      @subjects = Subject.all
      render :action => 'edit'
    end
  end
  def delete
    Book.find(params[:id]).destroy
    redirect_to :action => 'list'
  end

  private

  def book_params
    params.permit(:title, :price, :description)
  end

end

我该怎么办?,提前谢谢你

【问题讨论】:

  • @subject 在您看来很可能是未定义的。你的控制器是什么样的?也尝试重新启动您的服务器(错误和视图似乎不同意有问题的行的内容)

标签: ruby-on-rails ruby-on-rails-4


【解决方案1】:

你应该写

@book.subject.name

当然,您应该测试是否设置了subject。一种方法是写

@book.subject.try(:name)

如果subject 不为零,这将尝试name

还有一个一般性说明:不要从迁移中为数据库播种。通常您只会迁移一次,但当您进入生产或测试时,您将运行 rake db:setup,这将创建数据库架构而不运行迁移。

改为使用db/seed.rb 为数据库播种。这是一个可重复的过程,在运行测试(从干净/空的数据库开始)时也需要它。

【讨论】:

  • 我什至认为主题应该是属于 Book 类的常量或类方法
  • 非常感谢,这个方法解决了我的问题,我没有报错但是选择仍然没有出现
【解决方案2】:

根据你的错误

nil:NilClass 的未定义方法“名称”

Extracted source (around line #3):

 1 <h1><%= @book.title %></h1>
 2 <p><strong>Price: </strong> $<%= @book.price %><br />
 3 <strong>Subject: </strong> <%= @subject.name %><br />

@subject 在您的节目中为零。 因为你的控制器有

def show
  @book = Book.find(params[:id])
end

对于你的节目,情况似乎很可能是这样。

但是,您为节目发布的代码的行为

<strong>Subject: </strong> <%= @book.subject.name %><br />

我建议您尝试重新启动服务器,因为它似乎缓存了旧版本的视图。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多