Rails simple model attributes not saved to database - ruby-on-rails

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.

Related

Rails unable to save json in database

I want to save Json data in my Rails PostgreSQL database.
In my migration file
class IbmSubscription < ActiveRecord::Migration
def up
create_table :ibm_subscriptions do |t|
t.json 'ibm_response'
t.references :user, index: true
t.timestamps
end
end
def down
drop_table :ibm_subscriptions
end
end
I am unable to save JSON data in ibm_response
I tried this in rails console
2.1.5 :004 > a = JSON.parse(#uri.to_s)
=> {"type"=>"SUBSCRIPTION_ORDER", "marketplace"=>{"base_url"=>"https://acme.appdirect.com", "partner"=>"ACME"}, "flag"=>"STATELESS", "creator"=>{"email"=>"test-email+creator#appdirect.com", "first_name"=>"DummyCreatorFirst", "language"=>"fr", "last_name"=>"DummyCreatorLast", "open_id"=>"https://www.appdirect.com/openid/id/ec5d8eda-5cec-444d-9e30-125b6e4b67e2", "uuid"=>"ec5d8eda-5cec-444d-9e30-125b6e4b67e2"}, "payload"=>{"company"=>{"country"=>"CA", "email"=>"company-email#example.com", "name"=>"Example Company Name", "phone_number"=>"415-555-1212", "uuid"=>"d15bb36e-5fb5-11e0-8c3c-00262d2cda03", "website"=>"http://www.example.com"}, "configuration"=>{"entry"=>{"key"=>"domain", "value"=>"mydomain"}}, "order"=>{"edition_code"=>"BASIC", "pricing_duration"=>"MONTHLY", "item"=>[{"quantity"=>"10", "unit"=>"USER"}, {"quantity"=>"15", "unit"=>"MEGABYTE"}]}}, "return_url"=>"https://www.appdirect.com/finishprocure?token=dummyOrder", "#xmlns:atom"=>"http://www.w3.org/2005/Atom"}
2.1.5 :005 > a = IbmSubscription.create(ibm_response: #uri)
WARNING: Can't mass-assign protected attributes for IbmSubscription: ibm_response
(0.2ms) BEGIN
SQL (5.7ms) INSERT INTO "ibm_subscriptions" ("created_at", "updated_at") VALUES ($1, $2) RETURNING "id" [["created_at", Fri, 02 Oct 2015 17:30:13 UTC +00:00], ["updated_at", Fri, 02 Oct 2015 17:30:13 UTC +00:00]]
(93.9ms) COMMIT
=> #<IbmSubscription id: 1, ibm_response: nil, user_id: nil, created_at: "2015-10-02 17:30:13", updated_at: "2015-10-02 17:30:13">
Its creating ibm_response: nil.
Please help me. Thanks
Can't mass-assign protected attributes for IbmSubscription
This line implies that you need to add :ibm_response to attr_accessible in your IbmSubscription model.

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>

Attribute Not Updating

Model
class Pm < ActiveRecord::Base
attr_accessor :name
end
Console
me = Pm.new
#=> <Pm id: nil, name: nil, created_at: nil, updated_at: nil>
me.name = "Josh"
#=> "Josh"
me.save
#=>(0.4ms) BEGIN
#=> true
#=> SQL (0.8ms) INSERT INTO "pms" ("created_at", "name", "updated_at") VALUES ($1, $2, $3) RETURNING "id" [["created_at", Sat, 01 Jun 2013 19:02:27 UTC +00:00], ["name", nil], ["updated_at", Sat, 01 Jun 2013 19:02:27 UTC +00:00]]
#=>(1.3ms) COMMIT
me
#=> <Pm id: 4, name: nil, created_at: "2013-06-01 19:02:27", updated_at: "2013-06-01 19:02:27">
I have a model with a name attribute and an attr_accessor defined. The record saves but it doesn't update the name attribute. Am I missing something simple here?
If your Pmp model ("Pimp"? "Pump"? "Pimple"?) has a DB field called "name", there's no reason to use attr_accessor :name. With attr_accessor :name, ActiveRecord's dynamically generated attribute methods will never be invoked, and yes, it means the attribute won't be saved to the database.

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.

how to override model validation messages in rails 3

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

Resources