【问题标题】:ruby on rails engine undefined method 'delete' for nil:NilClassruby on rails 引擎未定义方法“删除”用于 nil:NilClass
【发布时间】:2013-05-29 20:39:22
【问题描述】:

我是 Ruby on Rails 的新手,使用的是 rails 3.2.13 和 ruby​​ 1.9.3p392。我正在尝试构建一个供应用使用的引擎,这可能会导致我的困惑。

引擎名称是 sales_app。我有一个页面将一堆数据发布到 sales_app/sales#create 以创建销售。在销售控制器的创建动作中,我做了一些数据处理并尝试实例化一个销售对象。我没有从模型中创建对象,而是得到了一个删除方法的 NoMethodError 异常,我什至不知道我正在调用该方法。请帮忙。

以下是相关细节。我的销售/新页面将以下参数发布到 sales#create:

{"sale"=>{"name"=>"Test",
 "desc"=>"This is a test",
 "start_date"=>"05/30/2013",
 "end_date"=>"05/31/2013",
 "start_time"=>"07:00",
 "end_time"=>"08:00",
 "products"=>""},
 "create"=>"Create Sale"}

Sales 控制器的创建操作如下:

def create
  if params[:create] == "Create Sale"
    # process the data - add a start and end to params
    #format = "%m/%d/%Y %H:%M:%S"
    params[:sale][:start] = DateTime.strptime("#{params[:sale][:start_date]} #{params[:sale][:start_time]}:00", '%m/%d/%Y %H:%M:%S')
    params[:sale][:end] = DateTime.strptime("#{params[:sale][:end_date]} #{params[:sale][:end_time]}:00", '%m/%d/%Y %H:%M:%S')
    @sale = Sale.new(:name => params[:sale][:name], :desc => params[:sale][:desc], :start => params[:sale][:start], :end => params[:sale][:end])
    if @sale.save
      redirect_to @sale
    else
      render 'new'
    end
  else
    render '/sales_app/static_pages/home'
  end      
end

日期内容旨在将日期和时间转换为单个日期时间,我认为这是可行的。 Sale 模型本身如下所示(我什至不确定为什么有些是这样的):

module SalesApp
  class Sale < ActiveRecord::Base
    attr_accessible :desc, :end, :name, :start
    def initialize(attributes = {})
      @name = attributes[:name]
      @desc = attributes[:desc]
      @start = attributes[:start]
      @end = attributes[:end]
    end

    validates :name, presence: true, length: { maximum: 255 }
    validates :desc, presence: true, length: { maximum: 65536 }
    validates :start, presence: true
    validates :end, presence: true
  end

end

我已经生成了我的模型并且我做了一个 rake db:migrate。我的架构如下所示:

ActiveRecord::Schema.define(:version => 20130527160623) do

  create_table "sales", :force => true do |t|
    t.string   "name"
    t.text     "desc"
    t.datetime "start"
    t.datetime "end"
    t.datetime "created_at", :null => false
    t.datetime "updated_at", :null => false
  end

end

架构文件在主应用程序中,但销售模型文件在引擎中。呃。

所以可能还有很多我可以做得更好的地方。不过,具体来说,我想知道为什么我不能创建一个 Sale 对象,或者我可能需要做什么来创建一个对象,或者至少为什么在我不知道原因的情况下调用了某种未定义的删除方法。任何帮助将不胜感激。谢谢!

EDIT Rake Routes 显示如下:

sales_app_static_pages_home GET    /sales_app/static_pages/home(.:format) sales_app/static_pages#home
sales_app_static_pages_help GET    /sales_app/static_pages/help(.:format) sales_app/static_pages#help
            sales_app_sales GET    /sales_app/sales(.:format)             sales_app/sales#index
                            POST   /sales_app/sales(.:format)             sales_app/sales#create
new_sales_app_sale          GET    /sales_app/sales/new(.:format)         sales_app/sales#new
edit_sales_app_sale         GET    /sales_app/sales/:id/edit(.:format)    sales_app/sales#edit
sales_app_sale              GET    /sales_app/sales/:id(.:format)         sales_app/sales#show
                            PUT    /sales_app/sales/:id(.:format)         sales_app/sales#update
                            DELETE /sales_app/sales/:id(.:format)         sales_app/sales#destroy
sales_app_root        /sales_app(.:format)                   sales_app/static_pages#home

【问题讨论】:

  • 你能发布rake routes的输出吗?
  • sales_app_static_pages_home GET /sales_app/static_pages/home(.:format) sales_app/static_pages#home sales_app_static_pages_help GET /sales_app/static_pages/help(.:format) sales_app/static_pages#help sales_app_sales GET /sales_app/sales (.:format) sales_app/sales#index POST /sales_app/sales(.:format) sales_app/sales#create
  • new_sales_app_sale GET /sales_app/sales/new(.:format) sales_app/sales#new edit_sales_app_sale GET /sales_app/sales/:id/edit(.:format) sales_app/sales#edit sales_app_sale GET / sales_app/sales/:id(.:format) sales_app/sales#show PUT /sales_app/sales/:id(.:format) sales_app/sales#update DELETE /sales_app/sales/:id(.:format) sales_app/sales #destroy sales_app_root /sales_app(.:format) sales_app/static_pages#home 糟糕的格式对不起
  • 发表你的问题,不要发表评论。
  • 这更有意义。

标签: ruby-on-rails ruby-on-rails-3 rails-engines


【解决方案1】:

我知道这是一个相当老的问题,这个答案并没有直接回答原始帖子,但如果其他人偶然发现“未定义的方法删除”错误并想知道发生了什么,它可能与您的方法名称。

具体来说,“initialize”方法似乎在 Rails 中被保留,就像在 Ruby 中一样。因此,如果您正在制作一种旨在将一些数据插入您的模型之一的方法(例如 before_validation :initialize),您将收到未定义的方法删除错误。将方法命名为其他名称(例如 before_validation :init_my_model),错误就会消失。

@Deranger 我怀疑是初始化方法搞砸了。

【讨论】:

  • 请参阅下面的评论,了解如何保留您的 initialize() 并获取 ActiveRecord 的初始化。
【解决方案2】:

if @sale.save
  redirect_to @sale 
else
  render 'new'
end

redirect_to @sale,@sale 将获取方法删除

改成

if @sale.save
  redirect_to sales_app_sales_path # or whatever do you want
else
  render 'new'
end

【讨论】:

  • 嗯。似乎无法得到任何不同的结果。即使我注释掉重定向或用渲染“新”替换它,我也会抛出相同的异常。不过,这至少给了我一些可以修补的东西。
  • 你能告诉我undefined method 'delete' for nil:NilClass的行吗?
  • SalesApp::SalesController 中的 NoMethodError #create undefined method 'delete' for nil:NilClass Rails.root: c:/Users/Robert/workspaces/[project_name]/[app_name]
【解决方案3】:

不管怎样,我已经解决了我遇到的任何问题,但我不确定问题在哪里解决了。以下是我做过的一些事情。

1) 在我的应用程序的 routes.rb 文件中,我已命名我的路由,而不是“挂载”它们。我通过添加更改它:mount [appname]::Engine => "/[root directory]", :as => "namespaced"。

2) 我将销售模型的 ":end" 和 ":start" 属性更改为 ":ending" 和 ":starting",只是因为 ":end" 似乎是一个非常不好用的术语。我回滚了我的迁移,编辑了迁移,并做了一个 rake db:migrate。

3) 在我的销售控制器中,我将 Sale.new(blahblahblah) 更改为 ::Sale.new(blahblahblah)。我不知道这是否有必要。我现在害怕触摸任何东西。

4) 在我的销售控制器中,我离开了 redirect_to @sale,它似乎符合我的预期。我确实将渲染 'new' 更改为 redirect_to 'some/page/here'。

5) 我从我的引擎中删除了销售模型,只在应用程序中保留了一个副本(以前,出于某种原因,我的引擎和应用程序中有一个销售模型)。此外,我注释掉了所有的“def initialize(attributes)”方法。甚至不确定那里在做什么,或者我是否需要它......

在此过程中可能还有其他一些变化。我真的不确定哪个更改实际上解决了问题,或者它是否是多种因素的组合。但我现在可以创建和操作模型对象了。

【讨论】:

    【解决方案4】:

    我刚刚在自己的代码中遇到了这个问题,并找到了一个简单的解决方案,我很确定它也会解决你的问题。

    当您将def initialize 添加到您的模型时,它会覆盖 ActiveRecord::Base 中的初始化方法,因此它永远不会被调用。我不完全清楚这如何导致对nil.delete() 的神秘调用,但修复它就像在初始化方法中添加对super 的调用一样简单:

    def initialize(attributes = {})
      @name = attributes[:name]
      @desc = attributes[:desc]
      @start = attributes[:start]
      @end = attributes[:end]
      super(attributes)  ### Add this line!
    end
    

    然后 ActiveRecord 开始设置它的所有魔力,和平笼罩大地。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-03-04
      • 1970-01-01
      • 1970-01-01
      • 2022-11-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多