why does klass.create(donor) always create a new donor while donors_controller#create does not
When I go to my donors_controller#create from a form in my view, it will update a record if it matches on ID or the collection of columns in my find_by_*
But if I call that create from a different controller, it always creates new records.
My donors_controller has a create method with:
def create
# need to find donor by id if given, else use find_or_create_by_blahblahblah
unless @donor = Donor.find_by_id(params[:donor][:id])
@donor = Donor.find_or_initialize_by_company_and_prefix1_and_first_name1_and_last_name1_and_address1(params[:donor])
end
if @donor.new_record?
...
else
...
end
end
M开发者_StackOverflowy other controller has :
class_name = 'Donor'
klass = ActiveRecord.const_get(class_name)
... code to populate myarray with appropriate values
klass.create(myarray)
I am pretty sure myarray is populated with the necessary params since it creates valid records with everything in the right place. I can even run the same record through more than once and it creates duplicate (except for the Donor.id of course) records.
What am I doing wrong here?
I noticed I could do this in my other controller and it works, but why can't I call the create from the donors_controller and have it work without always creating a new record?
#klass.create(myarray)
@mydonor = klass.find_or_initialize_by_company_and_prefix1_and_first_name1_and_last_name1_and_address1(myarray)
@mydonor.save
your question is very unclear and hard to follow, so i'm not sure my answer will match your needs. It seems you're confusing a controller#create method with a model#create method.
On the model : it is a class method
create
, as its name implies, instantiates a new
object of the Donor
class and calls save
on it:
@donor = Donor.create
# is the same thing as
@donor = Donor.new
@donor.save
Active Record uses new_record?
to determine if it should perform an insert or an update on the db when you call save
on an instanciated record. So with create
it will always be an insert since the record is inevitably new ; but if you call save
on a record retrieved from the database, it will be updated.
On a controller : it is an instance method
... but does not directly manages persistence, that's the role of the model. It is an action for this controller ; it is called create
for the sake of RESTful naming conventions. create
is called on a controller instance when a POST request is routed to it ; its purpose is to manage that request, which often (but not always) means to create records using the appropriate model, using YourModelName.new
or YourModelName.create
.
so it is absolutely possible (but not advisable) to do:
class DonorsController < ApplicationController
def create
# only works well if params[:donor][:id] is nil,
# will raise an error if a record with the
# same id exists in the database
@donor = Donor.create(params[:donor])
end
end
as it is generally needed to perform several operations before saving your record, and to check if save is successful, the process is broken down :
class DonorsController < ApplicationController
def create
@donor = Donor.new(params[:donor])
# perform operations on @donor (instance of Donor class)
if @donor.save # save returns true if successfully performed, false either
# all is fine
else
# @donor could not be saved
end
end
end
精彩评论