Reputation: 1089
I am tried to update attribute normally but it is not updating.
Here is my customer model
class Customer < ActiveRecord::Base
attr_accessible :name, :phone_number, :email
attr_accessible :first_name
attr_accessible :last_name
before_validation :parse_name
def name
"#{first_name} #{last_name}".strip
end
private
def parse_name
if attributes['name'].present?
self.first_name, self.last_name = attributes['name'].strip.split(' ', 2)
end
end
end
I tried to update first_name and last_name but it is not updating but if I tried to update email it is updating fine
Here is my rails console trace Updating email
2.1.0dev :004 > a = Customer.find(5)
Customer Load (0.2ms) SELECT `customers`.* FROM `customers` WHERE `customers`.`id` = 5 LIMIT 1
=> #<Customer id: 5, name: "First Last", phone_number: "1234567890", created_at: "2014-09-15 12:48:30", updated_at: "2014-09-15 14:32:17", first_name: "Fir
2.1.0dev :008 > a = Customer.find(5)
Customer Load (0.1ms) SELECT `customers`.* FROM `customers` WHERE `customers`.`id` = 5 LIMIT 1
=> #<Customer id: 5, name: "First Last", phone_number: "1234567890", created_at: "2014-09-15 12:48:30", updated_at: "2014-09-15 14:32:17", first_name: "Fir
st", last_name: "Last", email: "[email protected]">
2.1.0dev :009 > a.email = "[email protected]"
=> "[email protected]"
2.1.0dev :010 > a.save
(0.2ms) BEGIN
Customer Exists (0.2ms) SELECT 1 AS one FROM `customers` WHERE (`customers`.`phone_number` = BINARY '1234567890' AND `customers`.`id` != 5) LIMIT 1
(0.4ms) UPDATE `customers` SET `email` = '[email protected]', `updated_at` = '2014-09-15 20:38:31' WHERE `customers`.`id` = 5
(104.9ms) COMMIT
=> true
2.1.0dev :011 > a
=> #<Customer id: 5, name: "First Last", phone_number: "1234567890", created_at: "2014-09-15 12:48:30", updated_at: "2014-09-15 20:38:31", first_name: "Fir
st", last_name: "Last", email: "[email protected]">
But for updating first_name and last_name is not working
updating last_name
2.1.0dev :012 > a.last_name = "last_name"
=> "last_name"
2.1.0dev :013 > a.save
(0.2ms) BEGIN
Customer Exists (0.7ms) SELECT 1 AS one FROM `customers` WHERE (`customers`.`phone_number` = BINARY '1234567890' AND `customers`.`id` != 5) LIMIT 1
(0.2ms) COMMIT
=> true
2.1.0dev :014 > a.save!
(0.2ms) BEGIN
Customer Exists (0.2ms) SELECT 1 AS one FROM `customers` WHERE (`customers`.`phone_number` = BINARY '1234567890' AND `customers`.`id` != 5) LIMIT 1
(0.1ms) COMMIT
=> true
2.1.0dev :015 > a
=> #<Customer id: 5, name: "First Last", phone_number: "1234567890", created_at: "2014-09-15 12:48:30", updated_at: "2014-09-15 20:38:31", first_name: "Fir
st", last_name: "Last", email: "[email protected]">
Using update attributes
2.1.0dev :016 > a.update_attributes(:first_name => "test_name", :last_name => "test_name")
(0.2ms) BEGIN
Customer Exists (0.2ms) SELECT 1 AS one FROM `customers` WHERE (`customers`.`phone_number` = BINARY '1234567890' AND `customers`.`id` != 5) LIMIT 1
(0.2ms) COMMIT
=> true
2.1.0dev :017 > a
=> #<Customer id: 5, name: "First Last", phone_number: "1234567890", created_at: "2014-09-15 12:48:30", updated_at: "2014-09-15 20:38:31", first_name: "Fir
st", last_name: "Last", email: "[email protected]">
I tried to resolve it but it is not working.
Can any please tell me what I am missing.
I am using rails 3.2.14 and rails 2.1.0
Upvotes: 1
Views: 175
Reputation: 29588
Your before_validation
is overwriting the value you want to set. I would remove the parse name method all together and have the #name
method simply be a calculated value based on first_name
and last_name
e.g.
class Customer < ActiveRecord::Base
attr_accessible :phone_number, :email, :first_name, :last_name
def name
"#{first_name} #{last_name}".strip
end
end
If you really must have #name=
I would do it as
def name=(name_string)
self.first_name, self.last_name = name_string.strip.split(' ', 2)
end
You will have to save
for these values to hold. You could also do something like.
def update_name(name_string)
update_attributes(Hash[[:first_name,:last_name].zip(name_string.strip.split(' ', 2))])
end
Which will run save
with and return true
or false
based on validity
Upvotes: 2
Reputation: 3742
You have a before_validation method where first and last name are set depending on name. Your record already has a name, so it splits this name and extract first and last name.
Upvotes: 2