【问题标题】:NoMethodError in Books#show书籍中的 NoMethodError#show
【发布时间】:2014-03-20 12:33:47
【问题描述】:
    I am getting the following error I am new to ruby and rails

    I am using Rails4 with eclipse plugin the error is 
    NoMethodError in Books#show 

    undefined method `name' for nil:NilClass

    Extracted source (around line #3):  
    @book.subject.name I used associations in the model book which is belongs_to association with subject model.
    <h1><%= @book.title %></h1>
    <p><strong>Price: </strong> $<%= @book.price %><br />
    <strong>Subject: </strong> <%= link_to @book.subject.name,    #line number 3
    :action => "show_subjects", :id => @book.subject.id %><br />
    <strong>Created Date:</strong> <%= @book.created_at %><br />
    </p>

    app/views/books/show.erb:3:in `_app_views_books_show_erb___1047429498_14766720'
    actionpack (4.0.3) lib/action_view/template.rb:143:in `block in render'
    activesupport (4.0.3) lib/active_support/notifications.rb:161:in `instrument'
    actionpack (4.0.3) lib/action_view/template.rb:141:in `render'

    routes.rb file is

    LibrarayWebApplication::Application.routes.draw do
        get 'books/list'
        get 'books/new'
        post 'books/create'
        post 'books/update'
      get 'books/list'
       get 'books/show'
       get 'books/show_subjects'
      get 'books/edit'
        get 'books/delete'
          get 'books/update'
     get 'books/show_subjects'
    end

    my migrations files are

    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
      t.column :created_at, :timestamp
         end
      end

      def self.down
        drop_table :books
      end
    end

    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

    my controller files is

    class BooksController < ApplicationController
       def list
          @books = Book.find(:all)
       end
       def show
          @book = Book.find(params[:id])
       end
       def new
          @book = Book.new
          @subjects = Subject.find(:all)
       end
      #  private 
       def book_params
       params.require(:book).permit(:title,:price,:subject,:description)
       end
       def create
          @book = Book.new(book_params)
          if @book.save
                redirect_to :action => 'list'
          else
                @subjects = Subject.find(:all)
                render :action => 'new'
          end
       end


          def edit
          @book = Book.find(params[:id])
          @subjects = Subject.find(:all)
       end
      def update
            @book = Book.find(params[:id])

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

    show.erb file is
    I used associations in the model book which is belongs_to association with subject model.
    <h1><%= @book.title %></h1>
    <p><strong>Price: </strong> $<%= @book.price %><br />
        <strong>Subject: </strong> <%= link_to @book.subject.name, #this line I am getting error
    :action => "show_subjects", :id => @book.subject.id %><br />
    <strong>Created Date:</strong> <%= @book.created_at %><br />
    </p>
    <p><%= @book.description %></p>
    <hr />
    <%= link_to 'Back', {:action => 'list'} %>

    show_subjects file is

    <h1><%= @subject.name -%></h1>
    <ul>
    <% @subject.books.each do |c| %>
    <li><%= link_to c.title, :action => "show", :id => c.id -%></li>
    <% end %>
    </ul>

    I have two models 
    book.erb

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

I made associations between the models in book model I used belongs_to and in subject model I used has_many but I am getting that error If I remove the subject in show.erb the application working fine but when I include that line it showing that no such method

我在书籍模型中的模型之间建立了关联,我使用了belongs_to,在主题模型中我使用了has_many,但我收到了错误如果我在show.erb 中删除主题,应用程序工作正常,但是当我包含该行时,它显示没有这种方法 我在使用belongs_to的书籍模型和使用has_many的主题模型中的模型之间建立了关联,但我收到了这个错误如果我在show.erb中删除主题,应用程序工作正常但是当我包含该行时,它显示没有这样的方法

    subject.erb
    class Subject < ActiveRecord::Base
        has_many :books
    end

我写了@book.subject.name if @book.subject 这个语句避免了错误但它无法从数据库中检索主题名称

【问题讨论】:

  • 在 show.erb 文件中我使用了 Subject :
    这个命令运行良好并且显示像 Subject: ,但它不检索主题数据。我想像 Subject:subjectname 一样显示

标签: ruby-on-rails-4


【解决方案1】:

您收到未定义方法错误,因为您没有该特定书籍的主题。换句话说,您应该在实际调用 book.subject.name 之前检查是否存在书籍主题。

附:我会更改您的主题迁移(放弃 Subject.create '...' 部分)并使用资源 :books 作为您的路线,而不是单独定义所有路线。

【讨论】:

  • 在主题迁移中我有 subject.create na??
  • 如果我使用资源:书籍是需要写get/post还是不需要
  • 在迁移中创建主题没有意义,这实际上是一种不好的做法,应尽可能避免。如果您使用资源 :books,则不必定义所有 CRUD 路线。自定义路由可以通过在资源 :books 块中使用 member do ... end 或 collection do ... end 来定义。
  • 我删除了该代码主题:创建甚至它在 show.erb 早期错误中显示错误。我想向用户显示每个主题名称
  • 我不确定你的意思。您可以使用 book.subject.name,但您必须添加一个 if 条件以确保 book.subject 不为零(如:book.subject.present?)
【解决方案2】:

在 show.html.erb 中而不是 @book.subject.name 写为 @book.subject.try(:name)@book.subject.name if @book.subject

【讨论】:

  • 除非您有充分的理由这样做,否则我不会使用 try。我认为最后一个选项更清晰,更好。这就是为什么我也在我的回答中推荐了这个解决方案。尝试使您的代码更加灵活。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-01-05
  • 2016-08-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多