我有一个未定义的方法`name'为nil:NilClass,但我曾经工作过

时间:2016-09-26 09:20:27

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

我有这个未定义的方法“名字”,它曾经工作过......我不知道我搞砸了什么......我需要你的帮助...

index.html.slim

.container
  .row
    .col-xs-12
      h1.text-gray Tutorials 
      h4 Search by Title
      =form_tag tutos_path, :method => 'get' do 
        =text_field_tag :search, params[:search]
        =submit_tag "Search", class:'btn btn-default'

    .col-xs-12
      -if user_signed_in?
        = link_to "Create a tuto", new_tuto_path, class:"btn btn-success"


#tutos.transitions-enabled
  -@tutos.each do |tuto|
    .box.panel-default
      -if tuto.category.name == "Ruby"
        = link_to(image_tag("select/ruby.png"), tuto_path(tuto))
      -elsif tuto.category.name == "Rails 4"
        = link_to(image_tag("select/rails4.png"), tuto_path(tuto))
      -elsif tuto.category.name == "Rails 5"
        = link_to(image_tag("select/rails5.png"), tuto_path(tuto))
      -elsif tuto.category.name == "Heroku"
        = link_to(image_tag("select/heroku.png"), tuto_path(tuto))
      -elsif tuto.category.name == "AWS-Amazon"
        = link_to(image_tag("select/aws.png"), tuto_path(tuto))


      h3 = link_to tuto.title, tuto_path(tuto), class:"title-link"     
      h6 
        | Created by:
        span<>
        = tuto.user.full_name
      br
      span.glyphicon.glyphicon-heart
      span<>
      = tuto.get_upvotes.size
      br
      br

我的类别是在控制台中创建的:

 Category Load (1.4ms)  SELECT "categories".* FROM "categories"
 => #<ActiveRecord::Relation [#<Category id: 1, name: "Ruby", created_at: "2016-09-26 09:03:17", updated_at: "2016-09-26 09:03:17">, #<Category id: 2, name: "Rails 4", created_at: "2016-09-26 09:03:25", updated_at: "2016-09-26 09:03:25">, #<Category id: 3, name: "Rails 5", created_at: "2016-09-26 09:03:30", updated_at: "2016-09-26 09:03:30">, #<Category id: 4, name: "Heroku", created_at: "2016-09-26 09:03:35", updated_at: "2016-09-26 09:03:35">, #<Category id: 5, name: "AWS-Amazon", created_at: "2016-09-26 09:03:43", updated_at: "2016-09-26 09:03:43">]>
2.3.1 :002 >

tutos_controller.rb

class TutosController < ApplicationController
  before_action :authenticate_user!, only: [:new, :create]
  before_action :set_tuto, only: [:show, :edit, :update, :destroy, :upvote]


  def index
    @tutos = Tuto.all.includes(:user && :category)
    @categories = Category.all
    keyword_search
  end

  def show
    @tuto = Tuto.find(params[:id])
    @user = User.all
  end


  def new
    @tuto = Tuto.new
  end

  def edit
  end

  def create

    @tuto = Tuto.new(tuto_params)
    @tuto.user_id = current_user.id

    respond_to do |format|
      if @tuto.save
        flash[:success] = "Test"
        format.html { redirect_to @tuto, notice: 'Tuto was successfully created.' }
        format.json { render :show, status: :created, location: @tuto }
      else
        format.html { render :new }
        format.json { render json: @tuto.errors, status: :unprocessable_entity }
      end
    end
  end


  def update
    respond_to do |format|
      if @tuto.update(tuto_params)
        format.html { redirect_to @tuto, notice: 'Tuto was successfully updated.' }
        format.json { render :show, status: :ok, location: @tuto }
      else
        format.html { render :edit }
        format.json { render json: @tuto.errors, status: :unprocessable_entity }
      end
    end
  end


  def destroy
    @tuto.destroy
    respond_to do |format|
      format.html { redirect_to tutos_url, notice: 'Tuto was successfully destroyed.' }
      format.json { head :no_content }
    end
  end


  def upvote
    @tuto.upvote_by current_user
    redirect_to :back
  end


  def keyword_search
   @tutos = Tuto.search(params[:search])
  end

  private

    def set_tuto
      @tuto = Tuto.find(params[:id])
    end

    def tuto_params
      params.require(:tuto).permit(:title, :content, :id, :user_id, :category_id)
    end
end

架构

ActiveRecord::Schema.define(version: 20160920133801) do

  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 "tutos", force: :cascade do |t|
    t.datetime "created_at",  null: false
    t.datetime "updated_at",  null: false
    t.string   "title"
    t.text     "content"
    t.integer  "user_id"
    t.integer  "category_id"
  end

  add_index "tutos", ["user_id"], name: "index_tutos_on_user_id"

  create_table "users", force: :cascade do |t|
    t.string   "email",                  default: "", null: false
    t.string   "encrypted_password",     default: "", null: false
    t.string   "reset_password_token"
    t.datetime "reset_password_sent_at"
    t.datetime "remember_created_at"
    t.integer  "sign_in_count",          default: 0,  null: false
    t.datetime "current_sign_in_at"
    t.datetime "last_sign_in_at"
    t.string   "current_sign_in_ip"
    t.string   "last_sign_in_ip"
    t.datetime "created_at",                          null: false
    t.datetime "updated_at",                          null: false
    t.string   "first_name"
    t.string   "last_name"
    t.boolean  "admin"
  end

  add_index "users", ["email"], name: "index_users_on_email", unique: true
  add_index "users", ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true

  create_table "votes", force: :cascade do |t|
    t.integer  "votable_id"
    t.string   "votable_type"
    t.integer  "voter_id"
    t.string   "voter_type"
    t.boolean  "vote_flag"
    t.string   "vote_scope"
    t.integer  "vote_weight"
    t.datetime "created_at"
    t.datetime "updated_at"
  end

  add_index "votes", ["votable_id", "votable_type", "vote_scope"], name: "index_votes_on_votable_id_and_votable_type_and_vote_scope"
  add_index "votes", ["voter_id", "voter_type", "vote_scope"], name: "index_votes_on_voter_id_and_voter_type_and_vote_scope"

end

tuto_model.rb

class Tuto < ActiveRecord::Base
  acts_as_votable
  belongs_to :user
  belongs_to :category
  validates :category_id, presence: true


  def self.search(search)
    if search
      where(["title LIKE ?","%#{search}%"])
    else
      all
    end
  end
end

category_model.rb

class Category < ActiveRecord::Base
  has_many :tutos
end

修改

这是我对deepak建议的错误,(顺便说一句,我真的很喜欢他建议的重构!!)

index.html.slim:29: syntax error, unexpected ';', expecting ')' ...temple_html_pretty1)))).to_s)); ... ^

Extracted source (around line #29):
27
28
29
30
31
32

  -@tutos.each do |tuto|
    .box.panel-default
      = link_to image_tag(image_by_category(tuto.category.try(:name)), tuto_path(tuto)


      h3 = link_to tuto.title, tuto_path(tuto), class:"title-link"  

3 个答案:

答案 0 :(得分:2)

其中一个类别是nil,这就是你获得

的原因
  

未定义的方法&#34;名称&#34;为零:NilClass

使用try

<强> index.html.slim

-@tutos.each do |tuto|
  .box.panel-default
    -if tuto.category.try(:name) == "Ruby"
      = link_to(image_tag("select/ruby.png"), tuto_path(tuto))
    -elsif tuto.category.try(:name) == "Rails 4"
      = link_to(image_tag("select/rails4.png"), tuto_path(tuto))
    -elsif tuto.category.try(:name) == "Rails 5"
      = link_to(image_tag("select/rails5.png"), tuto_path(tuto))
    -elsif tuto.category.try(:name) == "Heroku"
      = link_to(image_tag("select/heroku.png"), tuto_path(tuto))
    -elsif tuto.category.try(:name) == "AWS-Amazon"
      = link_to(image_tag("select/aws.png"), tuto_path(tuto))

此外,我建议您在代码中使用辅助方法

<强> index.html.slim

-@tutos.each do |tuto|
  .box.panel-default
    = link_to image_tag(image_by_category(tuto.category.try(:name))), tuto_path(tuto)

<强> application_helper.rb

def image_by_category(name)
  images = {
    "Ruby" => "select/ruby.png",
    "Rails 4" => "select/rails4.png",
    "Rails 5" => "select/rails5.png",
    "Heroku" => "select/heroku.png",
    "AWS-Amazon" => "select/aws.png"
  }
  images[name]
end

答案 1 :(得分:1)

  

Tuto.all.includes(:user&amp;&amp;:category)

应该是

Tuto.all.includes(:user, :category)

答案 2 :(得分:1)

在这个@tutos循环中,你的一个类别不存在或者为nil,因此nil不存在name方法并且抛出错误,为此,你可以用两种方式解决它。

1)检查循环开始时是否存在类别(如果存在),然后仅进入,

-@tutos.each do |tuto|
    .box.panel-default
    -if tuto.category.present?
        -if tuto.category.name == "Ruby"
        = link_to(image_tag("select/ruby.png"), tuto_path(tuto))
        -elsif tuto.category.name == "Rails 4"
        = link_to(image_tag("select/rails4.png"), tuto_path(tuto))
        -elsif tuto.category.name == "Rails 5"
        = link_to(image_tag("select/rails5.png"), tuto_path(tuto))
        -elsif tuto.category.name == "Heroku"
        = link_to(image_tag("select/heroku.png"), tuto_path(tuto))
        -elsif tuto.category.name == "AWS-Amazon"
        = link_to(image_tag("select/aws.png"), tuto_path(tuto))

2)使用try继续执行而不检查错误

-@tutos.each do |tuto|
    .box.panel-default
      -if tuto.try(:category).try(:name) == "Ruby"
        = link_to(image_tag("select/ruby.png"), tuto_path(tuto))
      -elsif tuto.try(:category).try(:name) == "Rails 4"
        = link_to(image_tag("select/rails4.png"), tuto_path(tuto))
      -elsif tuto.try(:category).try(:name) == "Rails 5"
        = link_to(image_tag("select/rails5.png"), tuto_path(tuto))
      -elsif tuto.try(:category).try(:name) == "Heroku"
        = link_to(image_tag("select/heroku.png"), tuto_path(tuto))
      -elsif tuto.try(:category).try(:name) == "AWS-Amazon"
        = link_to(image_tag("select/aws.png"), tuto_path(tuto))