2

我是 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
4

4 回答 4

5

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

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

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

于 2014-01-25T00:39:40.700 回答
0

对于它的价值,我已经解决了我遇到的任何问题,但我不确定问题在哪里解决了。以下是我做的一些事情。

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,它似乎在做我预期的事情。我确实将渲染“新”更改为重定向_到“某些/页面/此处”。

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

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

于 2013-05-30T23:08:13.513 回答
0

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

redirect_to @sale, @sale 将获得方法 delete

改成

if @sale.save
  redirect_to sales_app_sales_path # or whatever do you want
else
  render 'new'
end
于 2013-05-29T21:46:02.537 回答
0

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

当您添加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 开始设置它的所有魔力,和平笼罩着这片土地。

于 2017-07-14T14:42:24.077 回答