【问题标题】:NoMethodError when generating new view生成新视图时出现 NoMethodError
【发布时间】:2014-11-05 05:12:23
【问题描述】:

我正在制作一个简单的应用程序,它的用户可以拥有许多播放列表。我正在尝试渲染播放列表的新视图,但出现此错误:

NoMethodError in PlaylistsController#new
undefined method `playlist' for nil:NilClass

  def new
    @playlist = @user.playlist.new
  end

这里有一些上下文:

编辑:我将代码的相关部分上传到了 gist.github:

https://gist.github.com/izikperz/164eab76e64d375d9075

播放列表控制器.rb

class PlaylistsController < ApplicationController
  before_action :set_playlist, only: [:show, :edit, :update, :destroy]
                :set_user

  # GET /playlists
  # GET /playlists.json
  def index
    @playlists = Playlist.all
  end

  # GET /playlists/1
  # GET /playlists/1.json
  def show
  end

  # GET /playlists/new
  def new
    @playlist = @user.playlist.new
  end

  # GET /playlists/1/edit
  def edit
  end

  # POST /playlists
  # POST /playlists.json
  def create
    @playlist = @user.playlists.new(playlist_params)

    respond_to do |format|
      if @playlist.save
        format.html { redirect_to @user.playlist, notice: 'Playlist was successfully created.' }
        format.json { render :show, status: :created, location: @playlist }
      else
        format.html { render :new }
        #format.json { render json: @playlist.errors, status: :unprocessable_entity }
      end
    end
  end

  # PATCH/PUT /playlists/1
  # PATCH/PUT /playlists/1.json
  def update
    respond_to do |format|
      if @playlist.update(playlist_params)
        format.html { redirect_to @playlist, notice: 'Playlist was successfully updated.' }
        format.json { render :show, status: :ok, location: @playlist }
      else
        format.html { render :edit }
        format.json { render json: @playlist.errors, status: :unprocessable_entity }
      end
    end
  end

  # DELETE /playlists/1
  # DELETE /playlists/1.json
  def destroy
    @playlist.destroy
    respond_to do |format|
      format.html { redirect_to playlists_url, notice: 'Playlist was successfully destroyed.' }
      format.json { head :no_content }
    end
  end

  private
    def set_user
      @user = User.find_by(params[:user_id])
    end
    # Use callbacks to share common setup or constraints between actions.
    def set_playlist
      @playlist = Playlist.find(params[:id])
    end

    # Never trust parameters from the scary internet, only allow the white list through.
    def playlist_params
      params.require(:playlist).permit(:user_id, :title, :img)
    end
end

在我的 routes.rb 我有:

resources :users do
    resources :playlists
  end

我的 user.rb 模型:

class User < ActiveRecord::Base
  before_save { self.email = email.downcase }
  has_secure_password
  validates :password, length: { minimum: 6 }
  has_many :playlists
end

Playlist.rb 模型:

class Playlist < ActiveRecord::Base
    belongs_to :user, inverse_of: :playlist
    validates :user_id, presence: true
end

我的数据库架构:

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

  create_table "playlists", force: true do |t|
    t.string   "title"
    t.string   "img"
    t.datetime "created_at"
    t.datetime "updated_at"
    t.integer  "user_id"
  end

  create_table "users", primary_key: "user_id", force: true do |t|
    t.string   "name"
    t.string   "email"
    t.datetime "created_at"
    t.datetime "updated_at"
    t.string   "password_digest"
    t.string   "imgurl"
  end

end

有人有什么想法吗?

【问题讨论】:

    标签: ruby-on-rails model-view-controller controller


    【解决方案1】:

    new 操作中的@user 对象是nil

    undefined method `playlist' for nil:NilClass
    

    这是因为 params[:user_id] 不是从您的视图中发送的。

    通过修改来修复它:

    new_user_playlist_path(params[:user_id])
    

    到:

    new_user_playlist_path(user_id: params[:user_id])
    

    修复该问题后,new 操作中会出现另一个错误:

    @playlist = @user.playlist.new
    

    它应该是复数的,因为它在你的协会中:

    @playlist = @user.playlists.new
    #or
    @playlist = @user.playlists.build
    

    或者干脆忽略:

    @playlist = Playlist.new(user_id: @user.id) 
    

    【讨论】:

    • 这是从我的角度发送它的方式吗?
    • 是的,假设params[:user_id] 包含user_id
    • @user2804881 修复了吗?
    • 我无法让它工作。这是我的更多代码......你能看看吗? gist.github.com/izikperz/164eab76e64d375d9075
    • 和昨天一样。我已经在上面的要点中列出了它
    【解决方案2】:

    由于用户和播放列表之间的 ActiveRecord 关联是 :has_many:belongs_to,因此这些关联是多对多的。这意味着一个用户有多个播放列表。该关联将为您提供实例方法@user.playlists 而不是@user.playlist。尝试使用复数版本。它应该可以工作。

    【讨论】:

      【解决方案3】:

      确保您将user_id 连同表单一起发送,以便

      @user = User.find_by(id: params[:user_id]) 不是nil

      然后改变这个

      @playlist = @user.playlists.new
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-02-04
        • 1970-01-01
        • 2010-11-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多