首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Rails未定义的方法“破坏”为nil:NilClass

Rails未定义的方法“破坏”为nil:NilClass
EN

Stack Overflow用户
提问于 2019-02-21 12:05:12
回答 6查看 1.2K关注 0票数 1

我在删除用户帖子时遇到了问题:

对于nil:NilClass的未定义的“破坏”方法

代码语言:javascript
复制
# routes.rb
Rails.application.routes.draw do
  get 'sessions/new'
  get 'users/new'
  get 'user/new'
  root to:'pages#home'
  get '/home', to:'pages#home'
  get '/help', to:'pages#help'
  get '/about', to:'pages#about'
  get '/contact',  to:'pages#contact'
  get '/signup', to: 'users#new'
  post '/signup', to: 'users#create'
  get '/login', to: 'sessions#new'
  post '/login', to: 'sessions#create'
  delete '/logout', to: 'sessions#destroy'
  post '/micro_posts', to: 'microposts#create'
  delete '/micro_posts', to: 'microposts#destroy'

  resources :users
  resources :account_activations, only: [:edit]
  resources :microposts, only: [:create, :destroy]
end


# microposts_controller.rb 

class MicropostsController < ApplicationController
  before_action :logged_in_user, only: [:create, :destroy]
  before_action :correct_user, only: [:destroy]

  def create
    @micropost = current_user.micro_posts.build(req_params)

    if @micropost.save
        flash[:success] = "Post created"
        redirect_to root_url    
    else
        @feed_items = []
        render 'pages/home'

    end     
  end

  def destroy   
    @micropost.destroy
    flash[:success] = "Post deleted"
    redirect_to request.referrer || root_url
  end    

  private

  def req_params
    params.require(:micro_post).permit(:content)
  end

  def correct_user
    @micropost = current_user.micro_posts.find_by_id(params[:id])
    redirect_to root_url if @micropost.nil?
  end    
end

# _micro_post.html.erb file

<li id="micropost" ><%= micro_post.id %>
  <%= link_to gravatar_for(micro_post.user, size: 50), micro_post.user %>
  <span class="user" ><%= link_to micro_post.user.name, micro_post.user %></span><br/>
  <span class="content" ><%= micro_post.content %></span>
  <br/> 
  <span  class="timestamp">
  posted <%= time_ago_in_words(micro_post.created_at) %> ago    

  <% if current_user?(micro_post.user) %>
    <%= link_to '  | Delete', micro_posts_path, method: :delete , data: { confirm: "Are you sure" } %>
  <% end %>    
  </span>
  <br/>    
</li>

现在我发现的是,我的错误在引用方法"correct_user“中的correct_user文件中,因为它找不到微博的id并返回零。所以我们不能调用nil对象的破坏方法。你能告诉我为什么它找不到微柱身份证吗?

代码语言:javascript
复制
Started DELETE "/micro_posts" for 127.0.0.1 at 2019-02-21 21:43:17 +0500
   (0.7ms)  SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
  ↳ C:/Ruby25-x64/lib/ruby/gems/2.5.0/gems/activerecord-5.2.2/lib/active_record/log_subscriber.rb:98
Processing by MicropostsController#destroy as HTML
  Parameters: {"authenticity_token"=>"aNeBnIy/JOrWz+sQdzU2w06faILW2dM+f8SPwmXVmJs1XfJ8OqbkgPVwkpoY/HBjh8YJhVPWZ4BC1Onxg0AtWw=="}
  User Load (0.2ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = ? LIMIT ?  [["id", 1], ["LIMIT", 1]]
  ↳ app/helpers/sessions_helper.rb:16
  MicroPost Load (0.3ms)  SELECT  "micro_posts".* FROM "micro_posts" WHERE "micro_posts"."id" IS NULL LIMIT ?  [["LIMIT", 1]]
  ↳ app/controllers/microposts_controller.rb:36
Completed 500 Internal Server Error in 56ms (ActiveRecord: 1.9ms)



NoMethodError (undefined method `destroy' for nil:NilClass):

app/controllers/microposts_controller.rb:22:in `destroy
EN

回答 6

Stack Overflow用户

发布于 2019-02-21 14:31:30

它看起来是correct_user方法中的问题。试着移除它并以这样的方式使用:

代码语言:javascript
复制
class MicropostsController < ApplicationController
  before_action :logged_in_user, only: [:create, :destroy]
  before_action :set_micropost, only: :destroy

  ...

  def set_micropost
    @micropost ||= Micropost.find params[:id]
  end
end

在你看来:

代码语言:javascript
复制
<%= link_to '  | Delete', @micropost, method: :delete , data: { confirm: "Are you sure" } %>
票数 1
EN

Stack Overflow用户

发布于 2019-02-21 17:36:51

如果你不介意的话,我会把我的意见转化为答案,不要把这个问题置之不理。

你的名字有问题。模型为MicroPost,而控制器为MicropostsController。这就是为什么你要创造定制路线。

您需要将控制器重命名为MicroPostsController,将它的文件重命名为micro_posts_controller.rb。从routes.rb中移除以下2行:

代码语言:javascript
复制
post '/micro_posts', to: 'microposts#create'
delete '/micro_posts', to: 'microposts#destroy'

并在这里将microposts更改为micro_posts (注意下划线):

代码语言:javascript
复制
resources :microposts, only: [:create, :destroy]

在视图中使用micro_post_path(micro_post)删除链接

票数 1
EN

Stack Overflow用户

发布于 2019-02-21 12:24:52

是的,你必须设置@micropost beofre试图摧毁它的价值。通常,这是您想要对params哈希做的事情,这样您就可以在@micropost = Micropost.find(params[:id])方法的开头得到类似于destroy的东西。这是您可能希望在控制器中的其他方法中使用的行,因此您可以如下所示重构它

代码语言:javascript
复制
class MicropostsController < ApplicationController
  before_action :set_micropost, only: [:destroy]

 ...

  private

  def set_micropost
    @micropost = Micropost.find(params[:id])
  end
end

希望它有帮助:)

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54806664

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档