mongoid update_attributes changed? - ruby-on-rails

I want to update_attributes and than check if information is changed
You can simply pass this code to rails console in existing rails + mongoid project
class TestModel
include Mongoid::Document
include Mongoid::Timestamps
field :name, type: String
end
test = TestModel.new({:name => "name 1"})
test.save()
=> true
test
=> created_at: 2012-11-14 13:48:26 UTC, updated_at: 2012-11-14 13:48:26 UTC
test.changed?
=> false
test.name_changed?
=> false
test.update_attributes({:name => "name 2"})
=> true
test.changed?
=> false
test.name_changed?
=> false
test
=> created_at: 2012-11-14 13:48:26 UTC, updated_at: 2012-11-14 13:49:23 UTC
Am I doing something wrong or this is a bug?

Its perfectly logic.
Dirty methods are meant to be used to check if an object has changed before it's saved. By definition a persisted object has no pending changes.
You should do:
test.assign_attributes(attributes)
test.changed? #=> true
test.save
See method definition.

Related

Mongoid in rails not saving document

I'm using rails 4.2.5 with mongoid 5.1.0 on windows 10 in dev mode. I have created a model "Signup" but it won't save to MongoDB. I can see that rails connects to MongoDB but no transactions are performned.
What am I missing?
Model code:
class Signup
include Mongoid::Document
field :email, type: String
field :date, type: DateTime, default: ->{ Time.now }
end
Console tests:
irb(main):034:0> s = Signup.create
=> #<Signup _id: 57b9d0436fc5511c04a945ce, email: nil, date: 2016-08-21 16:01:07 UTC>
irb(main):035:0> Signup.count
=> 0
irb(main):036:0> s.save!
=> true
irb(main):037:0> Signup.count
=> 0
irb(main):038:0>
found the solution, I used a dot in the database name in mongoid.yml (project.io) which somehow hindered db creation. I removed it (project_io) and everything is working now as it should.

how to prevent accepts_nested attributes_for from doing unnecessary validations in rails 2.3.5

I'm using accepts_nested_attributes_for in Rails 2.3.5 and find it does unnecessary validations on save.
In my application I have thousands of records so this is a problem.
To ilustrate this, I prepared a simple example.
class Language < ActiveRecord::Base
has_many :phrases
accepts_nested_attributes_for :phrases
end
class Phrase < ActiveRecord::Base
validates_presence_of :value
belongs_to :language
def before_validation
print "\nValidating: #{self.value}\n"
end
end
$ script/console
Loading development environment (Rails 2.3.5)
>> lang = Language.first
=> #<Language id: 1, name: "Italiano">
>> lang.phrases
=> [#<Phrase id: 7, value: "Buona notte", language_id: 1>,
#<Phrase id: 10, value: "Ciao", language_id: 1>,
#<Phrase id: 11, value: "Prego", language_id: 1>]
>> lang.phrases_attributes = [{:id => "7", :value => "Buon giorno"}]
=> [{:value=>"Buon giorno", :id=>"7"}]
>> lang.save
Validating: Buon giorno
Validating: Ciao
Validating: Prego
=> true
As this example shows it is validating not only the child that was added, but all other children.
Am I missing something?
How can I avoid doing all these validations?
As i indicated earlier, this is a real handicap for a large app.
After a suggestion I received from a Jason King of the SDRuby group I tried updating to 2.3.18.
That solved the problem

Rails3/Mongoid Validations Not Running

In my application, it seems that no ActiveModel validations are running, at all. That is, they always return true (valid) no matter how invalid the data actually is.
class QueueItem
include Mongoid::Document
include Mongoid::Timestamps
belongs_to :user
field :appointment_time, type: DateTime, allow_nil: true
field :notes, type: String, allow_nil: true
# field :position, type: Integer, default: 0
validates :user, presence: true, allow_blank: false, allow_nil: false
validates_length_of :notes, :minimum => 2, allow_blank: false
end
Then, when you try to save or validate a record with bad data, this is what you get:
ruby-1.9.2-p290 :028 > QueueItem.validators
=> [#<ActiveModel::Validations::PresenceValidator:0x007f8303adb190 #attributes=[:user], #options={:allow_blank=>false, :allow_nil=>false}>, #<ActiveModel::Validations::LengthValidator:0x007f8303ee5a60 #attributes=[:notes], #options={:minimum=>2, :allow_blank=>false}>]
ruby-1.9.2-p290 :029 > qi = QueueItem.new
=> #<QueueItem _id: 4edf5a0535be359a79000004, _type: nil, created_at: nil, updated_at: nil, user_id: nil, appointment_time: nil, notes: nil, called: false, visited: false, rejected: false>
ruby-1.9.2-p290 :030 > qi.notes = "x"
=> "x"
ruby-1.9.2-p290 :031 > qi.valid?
=> true
It seems that the validations are in fact being registered in the model, as shown by QueueItem.validations. Why, then, do they always return true? This is happening not just in this model, but in all models in my application.
UPDATE
I added a custom validator, and that is successfully firing.
validate :test_validation
def test_validation
logger.info ":test_validation has fired"
self.errors[:base] << "Something is royally screwed!"
end
Now, when I call model.valid?, it returns false, and the logger outputs that message. The custom validator is in fact adding errors to the object, and returning false. Still not clear why the standard ActiveModel ones are not being executed. Is there any way to trace these?
So, turns out that there was a corrupted string in the locals/en.yml file under the errors: section.

Mongoid persistance problems with a 1 to many association

I have the following model:
class Bill
. . . some fields . . .
belongs_to :sponsor, :class_name => "Legislator"
end
class Legislator
.. .some fields . . .
has_many :bills
end
I get this strange behavior, but I am sure this is something simple:
Loading development environment (Rails 3.0.7)
b = Bill.first
l = Legislator.first
l.bills << b
l.save
=> true
(I can view l.bills, but l.bills.all.to_a.count is 0)
l.govtrack_id
=> 400001
ruby-1.9.2-p180 :007 > Legislator.where(govtrack_id: 400001).first.bills
=> []
So I can create the association and view it. The save is successful, but when I retrieve the object, the association is gone . . . no errors. I'm confused, what am I missing?
You're missing inverse_of on your Legislator model. I ran a quick test (to make sure there wasn't a Mongoid issue). My models were thus:
class Bill
include Mongoid::Document
include Mongoid::Timestamps
field :name
belongs_to :sponsor, :class_name => "Legislator"
end
class Legislator
include Mongoid::Document
include Mongoid::Timestamps
field :govtrack_id
has_many :bills, :inverse_of => :sponsor
end
And console output from the test:
ruby-1.9.2-p180 > Bill.create(:name => "A new bill")
=> #<Bill _id: 4e0822636a4f1d11c1000001, _type: nil, created_at: 2011-06-27 06:25:39 UTC, updated_at: 2011-06-27 06:25:39 UTC, name: "A new bill", sponsor_id: nil>
ruby-1.9.2-p180 > Legislator.create(:govtrack_id => "400123")
=> #<Legislator _id: 4e0822786a4f1d11c1000002, _type: nil, created_at: 2011-06-27 06:26:00 UTC, updated_at: 2011-06-27 06:26:00 UTC, govtrack_id: "400123">
ruby-1.9.2-p180 > l = Legislator.first
ruby-1.9.2-p180 > l.bills << Bill.first
=> [#<Bill _id: 4e0822636a4f1d11c1000001, _type: nil, created_at: 2011-06-27 06:25:39 UTC, updated_at: 2011-06-27 06:26:08 UTC, name: "A new bill", sponsor_id: BSON::ObjectId('4e0822786a4f1d11c1000002')>]
ruby-1.9.2-p180 > l.save!
=> true
ruby-1.9.2-p180 > Bill.first.sponsor.govtrack_id
=> "400123"
ruby-1.9.2-p180 > Legislator.first.bills
=> [#<Bill _id: 4e0822636a4f1d11c1000001, _type: nil, created_at: 2011-06-27 06:25:39 UTC, updated_at: 2011-06-27 06:26:08 UTC, name: "A new bill", sponsor_id: BSON::ObjectId('4e0822786a4f1d11c1000002')>]

Rails3, Mongoid, cucumber. Can't set user_id field: illegal ObjectId format

I have an Account model:
class Account
include Mongoid::Document
include Mongoid::Timestamps
referenced_in :user
end
and User:
class User
include Mongoid::Document
include Mongoid::Timestamps
...
references_one :account
...
end
And the following scenario(i try to set reference_one association):
Scenario: Client views his account
Given the following accounts:
| user_id |
| 1123322131 |
.....
And the following step:
Given /^the following accounts:$/ do |class_name, table|
table.hashes.each do |attributes|
Account.create(attributes)
end
end
When I try to run cucumber, I always get an error:
illegal ObjectId format (BSON::InvalidObjectId)
./features/step_definitions/common_steps.rb:7:in `block (2 levels) in <top (required)>'
./features/step_definitions/common_steps.rb:6:in `each'
./features/step_definitions/common_steps.rb:6:in `/^the following accounts:$/'
features/manage_accounts.feature:8:in `And the following accounts:'
full version of backtrace: https://gist.github.com/433ea982d876e1b1fa27
I use: Rails 3.0.3, Ruby 1.9.2, cucumber 1.9.4, machinist 2, mongoid. My Gemfile
What did I do wrong?
UPD. No so obviously behaviour:
> a = Account.create :user_id => "123"
BSON::InvalidObjectId: illegal ObjectId format
> a = Account.create :user_id => 123
=> #<Account _id: 4ceedf055e6f991aef000005, created_at: 2010-11-25 22:11:17 UTC, updated_at: 2010-11-25 22:11:17 UTC, user_id: 123>
> a = Account.create :user_id => "4ceede9b5e6f991aef000007"
=> #<Account _id: 4ceedf1b5e6f991aef000006, created_at: 2010-11-25 22:11:39 UTC, updated_at: 2010-11-25 22:11:39 UTC, user_id: BSON::ObjectId('4ceede9b5e6f991aef000007')>
This could solve your problems:
Given /^the following accounts:$/ do |class_name, table|
table.hashes.each do |attributes|
User.create(attributes).create_account
end
end
Are you using a custom primary key for User? It seems that Mongoid is expecting a normal BSON::ObjectId like BSON::ObjectId('4ceeaf282b2d3a2ab0000001' but you are passing a plain string like 1123322131. In general, you have to be careful when trying to create a record and its associations at the same time

Resources