Reputation: 177
I'm new to Ruby on Rails, using rails 3.2.13 and ruby 1.9.3p392. I'm trying to build an engine to be used by an app, which might be contributing to my confusion.
Engine name is sales_app. I've got a page that posts a bunch of data to sales_app/sales#create to create a Sale. Inside the create action of the sales controller I do a little bit of data processing and try to instantiate a Sale object. Instead of creating an object from a model, I get a NoMethodError exception for a delete method that I didn't even know I was calling. Please help.
Here are the relevant details. My sales/new page posts the following parameters to 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"}
The Sales controller has the following for its create action:
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
The date stuff is intended to convert a date and a time to a single datetime and I think that's working. The Sale model itself looks like the following (I'm not even sure why some of this is like this):
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
I've generated my model and I did a rake db:migrate. My schema looks like this:
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
The schema file is in the main app, but the sale model file is in the engine. Ugh.
So there's probably a whole lot that I can do better. Specifically, though, I want to know why I can't create a Sale object or what I might need to do to create one, or at least why some kind of undefined delete method is being called without me knowing why. Any assistance would be much appreciated. Thanks!
EDIT Rake Routes shows the following:
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
Upvotes: 2
Views: 5965
Reputation: 6287
I just ran into this problem in my own code, and found a simple solution, which I'm pretty sure will fix yours as well.
When you add def initialize
to your model, it overrides the initialize method in ActiveRecord::Base, such that it never gets called. I'm not entirely clear how that leads to the mysterious call to nil.delete()
, but fixing it is as simple as adding a call to super
in your initialize method:
def initialize(attributes = {})
@name = attributes[:name]
@desc = attributes[:desc]
@start = attributes[:start]
@end = attributes[:end]
super(attributes) ### Add this line!
end
Then ActiveRecord gets to set up all it's mojo, and peace blankets the land.
Upvotes: 0
Reputation: 365
I know this is a rather old question and this answer doesn't directly answer the original post, but in case anyone else stumbles upon the "undefined method delete" error and wonders what's going on, it might have to do with your method names.
Specifically, it seems that the method "initialize" is reserved in Rails as it is in Ruby. Thus if you're making a method intended to plug some data into one of your models (e.g. before_validation :initialize) you'll get the undefined method delete error. Name the method something else (e.g. before_validation :init_my_model) and the error will go away.
@Deranger I suspect that the initialize method was the one mucking things up.
Upvotes: 5
Reputation: 177
For what it's worth, I've fixed whatever problem I was having and I'm not certain where along the way the problem cleared up. Here are some things that I did.
1) In my app's routes.rb file, I had namespaced my routes instead of "mounting" them. I changed that by adding: mount [appname]::Engine => "/[root directory]", :as => "namespaced".
2) I changed my sale model's ":end" and ":start" attributes to ":ending" and ":starting," just because ":end" seemed like a really bad term to use. I rolled back my migrations, edited the migrations, and did a rake db:migrate.
3) In my sales controller, I changed my Sale.new(blahblahblah) to ::Sale.new(blahblahblah). I don't know if this is necessary. I'm afraid to touch anything right now to see.
4) In my sales controller, I left the redirect_to @sale and it seems to be doing what I expected. I did change the render 'new' to redirect_to 'some/page/here'.
5) I deleted the Sale model from my engine, leaving only a copy in the app (previously, I had a sale model in my engine and in my app for some reason). Further, I commented out all of the "def initialize(attributes)" method. Not even sure what that was doing in there, or if I need it...
There may have been some other changes along the way. I'm really not sure which change actually fixed things, or whether it was a combination of factors. But I can now create and manipulate model objects.
Upvotes: 0
Reputation: 8220
See
if @sale.save
redirect_to @sale
else
render 'new'
end
redirect_to @sale
, @sale will get method delete
change to
if @sale.save
redirect_to sales_app_sales_path # or whatever do you want
else
render 'new'
end
Upvotes: 0