how to override model validation messages in rails 3 - ruby-on-rails

I have a model,group_question_answer.rb
class GroupQuestionAnswer < ActiveRecord::Base
belongs_to :group_question
validates_presence_of :answer
validates_presence_of :answer_question
end
for attribute answer and answer_question i get error message as Group question answers answer can't be blank
I need to show only answer cant be blank.i even tried adding :message=>"cant be blank",but still i dont get my required message.how can i remove model name and can just arrtibute error message ....

class GroupQuestionAnswer < ActiveRecord::Base
attr_accessible :answer
validate do |group_question_answer|
errors.add(:base, "answer can't be blank") if group_question_answer.answer.blank?
end
end
works perfectly
rails c
Loading development environment (Rails 3.2.9)
irb(main):001:0> q = GroupQuestionAnswer.create
(0.1ms) begin transaction
(0.1ms) rollback transaction
=> #<GroupQuestionAnswer id: nil, answer: nil, created_at: nil, updated_at: nil>
irb(main):002:0> q
=> #<GroupQuestionAnswer id: nil, answer: nil, created_at: nil, updated_at: nil>
irb(main):003:0> q.save
(0.1ms) begin transaction
(0.1ms) rollback transaction
=> false
irb(main):004:0> q.errors
=> #<ActiveModel::Errors:0x007fc2fb325fa8 #base=#<GroupQuestionAnswer id: nil, answer: nil, created_at: nil, updated_at: nil>, #messages={:base=>["answer can't be blank"]}>
irb(main):006:0> q.errors.messages
=> {:base=>["answer can't be blank"]}
=> {:base=>["answer can't be blank"]}
irb(main):007:0> q = GroupQuestionAnswer.create(answer: "123")
(0.1ms) begin transaction
SQL (9.0ms) INSERT INTO "group_question_answers" ("answer", "created_at", "updated_at") VALUES (?, ?, ?) [["answer", "123"], ["created_at", Fri, 28 Dec 2012 11:01:38 UTC +00:00], ["updated_at", Fri, 28 Dec 2012 11:01:38 UTC +00:00]]
(1.1ms) commit transaction
=> #<GroupQuestionAnswer id: 1, answer: "123", created_at: "2012-12-28 11:01:38", updated_at: "2012-12-28 11:01:38">
irb(main):008:0> q.errors.messages
=> {}
In my opinion validate method perfect way to fully customize rails validations and that does exactly what you ask for.

You can try like this:
validates :answer, presence: { message: '<Your message>'}
validates :answer_question, presence: { message: '<Your message>'}

Try adding them in your config/locales/en.yml file
As there you can do something like this,
en:
errors:
messages:
answer: answer can't be blank

Related

Rails simple model attributes not saved to database

I am developing a small Rails 3 app that reads data from the Steam API. What I am seeing is that the model attributes for any ActiveRecord model I create are not saved to the database nor are they output if I debug them.
Here my sample model
class NonPlayableApp < ActiveRecord::Base
attr_accessor :name, :steam_id
attr_accessible :name, :steam_id
end
With the migration file being:
class CreateNonPlayableApps < ActiveRecord::Migration
def change
create_table :non_playable_apps do |t|
t.string :name
t.string :steam_id
t.timestamps
end
end
end
Here are few tests with the Rails console, I get the same results when I try them in a controller and inspect or yaml the model:
irb(main):001:0> temp = NonPlayableApp.new( steam_id: 33333, name: "Testing" )
=> #<NonPlayableApp id: nil, name: nil, steam_id: nil, created_at: nil, updated_at: nil>
irb(main):002:0> temp.steam_id
=> 33333
irb(main):003:0> temp.name
=> "Testing"
irb(main):004:0> temp.save
(0.1ms) begin transaction
SQL (4.0ms) INSERT INTO "non_playable_apps" ("created_at", "name", "steam_id", "updated_at") VALUES (?, ?, ?, ?) [["created_at", Fri, 26 Feb 2016 19:40:37 UTC +00:00], ["name", nil], ["steam_id", nil], ["updated_at", Fri, 26 Feb 2016 19:40:37 UTC +00:00]]
(8.8ms) commit transaction
=> true
irb(main):005:0> temp.steam_id
=> 33333
irb(main):006:0> temp
=> #<NonPlayableApp id: 64, name: nil, steam_id: nil, created_at: "2016-02-26 19:40:37", updated_at: "2016-02-26 19:40:37">
irb(main):007:0> temp2 = NonPlayableApp.first
NonPlayableApp Load (1.6ms) SELECT "non_playable_apps".* FROM "non_playable_apps" LIMIT 1
=> #<NonPlayableApp id: 64, name: nil, steam_id: nil, created_at: "2016-02-26 19:40:37", updated_at: "2016-02-26 19:40:37">
irb(main):008:0> temp2.steam_id
=> nil
irb(main):009:0> temp2.name
=> nil
What am I missing?
attr_accessor :name, :steam_id overrides the setter and getter methods that Rails automatically generates for that attributes.
Just delete the attr_accessor :name, :steam_id line from your model.

Rails console ignores attributes set with attr_accessor, and has_secure_password causes the password and the password_confirmation to be ignored [duplicate]

This question already has an answer here:
Rails model fields not updating to database
(1 answer)
Closed 7 years ago.
User model:
class User < ActiveRecord::Base
attr_accessor :name, :email
has_secure_password
validates :password, presence: true, length: { minimum: 6 }
end
The problem is, in the Rails console, the attributes name, email, password, password_confirmation don't show up.
I suspect the first two are caused due to setting attr_accessor :name, :email and the latter two due to has_secure_password
But, when I call those attributes separately, they show up:
Loading development environment (Rails 4.2.0)
2.2.1 :001 > u = User.new(name: "asd", email: "aedede#aece.com", password: "qweasd", password_confirmation: "qweasd")
=> #<User id: nil, name: nil, email: nil, created_at: nil, updated_at: nil, password_digest: "$2a$10$a98/zxfH0zaT0Hh.xalVPOxwbJiXAkH17BiRg.sV4hw...">
2.2.1 :002 > u
=> #<User id: nil, name: nil, email: nil, created_at: nil, updated_at: nil, password_digest: "$2a$10$a98/zxfH0zaT0Hh.xalVPOxwbJiXAkH17BiRg.sV4hw...">
2.2.1 :003 > u.name
=> "asd"
2.2.1 :004 > u.email
=> "aedede#aece.com"
2.2.1 :005 > u.password
=> "qweasd"
2.2.1 :009 > u.save
(0.2ms) begin transaction
User Exists (0.2ms) SELECT 1 AS one FROM "users" WHERE LOWER("users"."email") = LOWER('aedede#aece.com') LIMIT 1
SQL (0.4ms) INSERT INTO "users" ("password_digest", "created_at", "updated_at") VALUES (?, ?, ?) [["password_digest", "$2a$10$a98/zxfH0zaT0Hh.xalVPOxwbJiXAkH17BiRg.sV4hwFXp2jUiTnm"], ["created_at", "2015-06-10 02:42:22.437148"], ["updated_at", "2015-06-10 02:42:22.437148"]]
(130.8ms) commit transaction
=> true
2.2.1 :010 > u
=> #<User id: 3, name: nil, email: nil, created_at: "2015-06-10 02:42:22", updated_at: "2015-06-10 02:42:22", password_digest: "$2a$10$a98/zxfH0zaT0Hh.xalVPOxwbJiXAkH17BiRg.sV4hw...">
2.2.1 :011 > u.name
=> "asd"
I've checked everything thoroughly and can't find what's causing this, any insights to what's actually happening under the hood would be deeply appreciated.
password is not a column in your database users, and neither it should be. It is just an attribute. If you have used has_secure_password, and you have - Rails will automatically take the password you specified, encrypt it, and store a password_digest in the database. There would be not password column in the database.
In Rails 4.2, you don't need to write attr_accessor with your column names in your model. If you have defined them in migration, Rails will automagically create getter/setter and a bunch of other helping methods for you. So, you model User should look like following in Rails 4.2:
class User < ActiveRecord::Base
has_secure_password
validates :password, presence: true, length: { minimum: 6 }
end

allow_nil: false does not work from rails console

Newbie here, trying to add some rules to a ruby on rails form, specifically I don't want to allow the creation of an item if this has not a name
class Idea < ActiveRecord::Base
mount_uploader :picture, PictureUploader
belongs_to :project
validates :name, presence: true, allow_nil: false
end
Works smoothly if I create a new item from my app, but not happens the same if I create one item from rails console. How can I avoid the creation of an item without name, no matter if this has been created in the app or in the rails console?
The problem is you have to set allow_blank: false instead of allow_nil: false.
In Ruby an empty string is not nil.
"".nil?
#=> false
"".blank?
#=> true
Update your model like this
class Idea < ActiveRecord::Base
mount_uploader :picture, PictureUploader
belongs_to :project
validates :name, presence: true, allow_blank: false
end
If you want know the differences between nil and blank,see this SO post.
Refer these Guides for allow_blank
Try this from console:-
Idea.create(:name => "Something")
Rails console output:-
1.9.3-p385 :005 > c = CabinNumber.create(:name => "Something")
(0.2ms) begin transaction
SQL (1.1ms) INSERT INTO "cabin_numbers" ("created_at", "name", "status", "updated_at") VALUES (?, ?, ?, ?) [["created_at", Sun, 25 May 2014 00:02:04 IST +05:30], ["name", "Something"], ["status", false], ["updated_at", Sun, 25 May 2014 00:02:04 IST +05:30]]
(139.6ms) commit transaction
=> #<CabinNumber id: 11, name: "Something", status: false, created_at: "2014-05-24 18:32:04", updated_at: "2014-05-24 18:32:04">
OR
idea = Idea.new(:name => "hello")
idea.save
Rails console output:-
1.9.3-p385 :007 > c = CabinNumber.new(:name => "hello")
=> #<CabinNumber id: nil, name: "hello", status: false, created_at: nil, updated_at: nil>
1.9.3-p385 :008 > c.save
(0.1ms) begin transaction
SQL (1.0ms) INSERT INTO "cabin_numbers" ("created_at", "name", "status", "updated_at") VALUES (?, ?, ?, ?) [["created_at", Sun, 25 May 2014 00:02:57 IST +05:30], ["name", "hello"], ["status", false], ["updated_at", Sun, 25 May 2014 00:02:57 IST +05:30]]
(155.0ms) commit transaction
=> true
Cannot create if name field is not provided
1.9.3-p385 :003 > c = CabinNumber.create()
(0.2ms) begin transaction
(0.1ms) rollback transaction
=> #<CabinNumber id: nil, name: nil, status: false, created_at: nil, updated_at: nil>

Rails console outputs dirty/outdated data

I'm following Michael's Ruby on Rails tutorial (Chapter 6.2.2) and when I go to the rails console --sandbox to attempt to create Users the outputs come totally outdated.
I update a user's attribute, I return the user and the console outputs nil for all attributes. However if I output the user.attribute the data is there.
The first save fails because a user must have a name, though I had this problem even before addind validations.
What am I missing here? I followed all the instructions and I'm doing pretty basic stuff. I'm executing the following commands:
$ rails console --sandbox
Loading development environment in sandbox (Rails 4.0.2)
Any modifications you make will be rolled back on exit
2.1.0 :001 > user = User.new(name: "", email: "mhartl#example.com")
=> #<User id: nil, name: nil, email: nil, citizen_number: nil, created_at: nil, updated_at: nil>
2.1.0 :002 > user.save
(0.1ms) SAVEPOINT active_record_1
(0.2ms) ROLLBACK TO SAVEPOINT active_record_1
=> false
2.1.0 :003 > user.valid?
=> false
2.1.0 :004 > user.name = "Bob"
=> "Bob"
2.1.0 :005 > user.valid?
=> true
2.1.0 :006 > user
=> #<User id: nil, name: nil, email: nil, citizen_number: nil, created_at: nil, updated_at: nil>
2.1.0 :007 > user.save
(0.2ms) SAVEPOINT active_record_1
SQL (6.2ms) INSERT INTO "users" ("created_at", "updated_at") VALUES (?, ?) [["created_at", Sat, 08 Feb 2014 19:15:37 UTC +00:00], ["updated_at", Sat, 08 Feb 2014 19:15:37 UTC +00:00]]
(0.1ms) RELEASE SAVEPOINT active_record_1
=> true
2.1.0 :008 > user
=> #<User id: 1, name: nil, email: nil, citizen_number: nil, created_at: "2014-02-08 19:15:37", updated_at: "2014-02-08 19:15:37">
My user model:
class User < ActiveRecord::Base
attr_accessor :name, :email, :citizen_number
VALID_EMAIL_REGEX = /\A[\w+\-.]+#[a-z\d\-.]+\.[a-z]+\z/i
VALID_CITIZEN_NUMBER_REGEX = /[1-9]\d{7,}/
validates :name, presence: true, length: { maximum: 50 }
validates :email, presence: true, format: { with: VALID_EMAIL_REGEX }, uniqueness: { case_sensitive: false }
validates :citizen_number, presence: true, format: { with: VALID_CITIZEN_NUMBER_REGEX }, uniqueness: true
before_save { lowercase_email() }
def lowercase_email()
self.email = email.downcase
end
end
DiAlex, do you have the code that produced this? I'd like to try it. Since the issue is actually something that happens before the save but after "initialization", I can't see how reload or the validations matter.
Update: Based on the tests and back and forth with you, I think your problem is related with the misuse of attr_accessor and attr_accessible.
Try removing :citizen_number from the attr_accessor. I tried that and your code started working (passing all your tests) and the console started outputting the correct values too.
Use reload
user.reload should give your up to date user with the correct attributes, as explained in the Documentation, it reloads the attributes of this object from the database, so you can now get the object attributes as expected, if they saved correctly
Diogo, something is preventing your user.save. After the first attempt of user.save, try user.errors. This will give you a hash with the errors that prevented your model to save.
Most probably you will find an error in your DB Scheme, as the user.valid? returns true.
Have you tried without sandbox mode? Perhaps it is somehow restricting the write.
rails console

Strange ActiveRecord model behavior

I have model
class Owner < ActiveRecord::Base
attr_accessible :telephone
validates_uniqueness_of :telephone
validates_telephone_number_of :telephone
before_validation :telephone_normalize
end
in rails console
a = Owner.new(:telephone => '949123456')
=> #<Owner id: nil, telephone: "949123456", created_at: nil, updated_at: nil>
1.9.3-p362 :002 > a.valid?
Owner Exists (0.1ms) SELECT 1 AS one FROM "owners" WHERE "owners"."telephone" = '+421949123456' LIMIT 1
=> false
1.9.3-p362 :003 > a
=> #<Owner id: nil, telephone: "421949123456", created_at: nil, updated_at: nil>
The same, when I save unique number:
1.9.3-p362 :006 > a.telephone = '949123457'
=> "949123457"
1.9.3-p362 :007 > a.save
(0.1ms) begin transaction
Owner Exists (0.2ms) SELECT 1 AS one FROM "owners" WHERE "owners"."telephone" = '+421949123457' LIMIT 1
SQL (2.3ms) INSERT INTO "owners" ("created_at", "telephone", "updated_at") VALUES (?, ?, ?) [["created_at", Wed, 16 Jan 2013 11:55:44 UTC +00:00], ["telephone", "421949123457"], ["updated_at", Wed, 16 Jan 2013 11:55:44 UTC +00:00]]
(88.3ms) commit transaction
=> true
Rails (3.2.11) omits '+' in the beginning of number. Type of number is string. It also saves it without plus sign (if it is unique), but when validating, it calls with plus sign.
What am I doing wrong?
It think telephone column in database is integer type. So the string you have passed is out of its range. That's why you have face this problem.
Unfortunetaly there was bug in my validates_telephone_number_of validator. It had modified attribute :-/
Say
> a = 'aaa' # => 'aaa'
> b = a.to_s # => 'aaa'
> b << 'c' # => 'aaac'
> b # => 'aaac'
> a # => 'aaac'
It is needed to use b = a.to_s.dup.

Resources