check if object has been updated mongoid 3.x - ruby-on-rails

1.9.3p448 :014 > l.reload
=> #<Lesson _id: 527246641d41c81d14000006, title: "ola">
1.9.3p448 :015 > l.changed?
=> false
1.9.3p448 :016 > l.changes
=> {}
1.9.3p448 :017 > l.previous_changes
=> {"title"=>["olaaaaa", "ola"]}
1.9.3p448 :018 > l.changed?
=> false
1.9.3p448 :019 > l.update_attributes(title: "olaaa")
=> true
1.9.3p448 :020 > l.changes
=> {}
1.9.3p448 :021 > l.changed?
=> false
I have updated the attribute "title" but when I try l.changed? I get false.
I know the new_record? method, to know if a object is a new object but I need to know if a object is updated.
I would like to know, how can I know if a object has been updated with mongoid 3.x?

When you reload, save, update, the changes are moved to previous_changes. You also have access to the changes on callbacks, otherwise you will have to use previous_changes .
Thats by design, to be consistent with ActiveRecord.

Related

Check values in a hash

I am working on a legacy Rails project that uses Ruby 1.8 .
I have an hash of key-value where value is a float number.
For example, my_hash = ['foo'=>12.20, 'bar'=>10.0]. How can I check if my_hash contains all zero values? e.g. ['foo'=>0, 'bar'=>0, 'whatever'=>0] or ['foo'=>0.0, 'bar'=>0, 'whatever'=>0.0].
I know I can loop through & check element one by one, but I just wonder is there a more elegant way?
use below code if my_hash is:
[{"foo"=>0.0, "bar"=>0, "whatever"=>0.0}]
my_hash.first.values.all?{|item| item.zero?}
or if my_hash is array, just:
my_hash.all?{|item| item.zero?}
Check all values in the hash are zero or not?
2.2.3 :006 > h={"foo"=>0.0, "bar"=>0, "whatever"=>0.0}
=> {"foo"=>0.0, "bar"=>0, "whatever"=>0.0}
2.2.3 :007 > h.values.all?{|a| a.zero?}
=> true
If it is an array of hash then
2.2.3 :001 > h = ['foo'=>0.0, 'bar'=>0, 'whatever'=>0.0]
=> [{"foo"=>0.0, "bar"=>0, "whatever"=>0.0}]
2.2.3 :004 > h[0].values.all?{|a| a.zero? }
=> true
OR
2.2.3 :014 > h
=> [{"foo"=>0.0, "bar"=>0, "whatever"=>0.0}]
2.2.3 :015 > h.first.values.all?{|a| a.zero?}
=> true
Any element is zero
2.2.3 :009 > h={"foo"=>0.0, "bar"=>2, "whatever"=>1.1}
=> {"foo"=>0.0, "bar"=>2, "whatever"=>1.1}
2.2.3 :010 > h.values.any?{|a| a.zero?}
=> true
2.2.3 :011 > h={"foo"=>0.2, "bar"=>2, "whatever"=>1.1}
=> {"foo"=>0.2, "bar"=>2, "whatever"=>1.1}
2.2.3 :012 > h.values.any?{|a| a.zero?}
=> false

simple_format changes the text itself

In Rails 3.0, the helper method simple_format changes the parameter itself.
I expected that it only returns the wrapped text.
2.0.0-p648 :001 > Rails.version
=> "3.0.20"
2.0.0-p648 :002 > s = "Hello"
=> "Hello"
2.0.0-p648 :003 > helper.simple_format(s)
=> "<p>Hello</p>"
2.0.0-p648 :004 > s
=> "<p>Hello</p>"
I checked with Rails 4.2 and it doesn't change the text.
Can someone please explain it?
Sam
The difference between implementations of this method in Rails 4.2 and Rails 3.0 is that in Rails 3.0 the passed string is modified (mutated by gsub!) and in Rails 4.2 it's not (it just returns a new modified string):
Rails 4.2:
2.4.0 :006 > s = "hello"
=> "hello"
2.4.0 :007 > simple_format s
=> "<p>hello</p>"
2.4.0 :008 > s
=> "hello"
The source code of different implementations can be found in the documentation

ActiveRecord class (enum) behaving incorrectly with patch in config/initializers

I'm using ruby 2.2.3 and rails 4.2.4.
Background: I need the ability to re-use values across enums within the same model so I have patched in the latest version of Active Record's enum.rb as config/initializers/enum_patch.rb since they are adding prefix/suffix support in Rails 5 which will enable this functionality.
Issue: After patching in the code, Enum is no longer working correctly. See below:
class GatheringSession < ActiveRecord::Base
GatheringStates = %i(ready running finished errored)
enum :gathering_state => GatheringStates
...
end
Console (no patch). Correct behaviour:
2.2.3 :001 > gs2 = GatheringSession.last
=> #<GatheringSession id: 120, gathering_state: 2 ... >
2.2.3 :002 > gs2.gathering_state
=> "finished"
2.2.3 :003 > gs2.ready?
=> false
2.2.3 :004 > gs2.finished?
=> true
2.2.3 :005 > gs2.ready!
=> true
2.2.3 :007 > gs2.ready?
=> true
2.2.3 :008 > gs2.finished?
=> false
2.2.3 :009 > gs2.finished!
=> true
2.2.3 :010 > gs2.finished?
=> true
Console (patch):
2.2.3 :001 > gs2 = GatheringSession.last
=> #<GatheringSession id: 120, gathering_state: 2 ... >
2.2.3 :002 > gs2.gathering_state
=> 2
2.2.3 :003 > gs2.ready?
=> false
2.2.3 :004 > gs2.finished?
=> false
2.2.3 :005 > gs2.ready!
(0.2ms) BEGIN
SQL (0.8ms) UPDATE `gathering_sessions` SET `gathering_state` = 'ready', `updated_at` = '2015-10-31 00:28:36' WHERE `gathering_sessions`.`id` = 120
Mysql2::Error: Incorrect integer value: 'ready' for column 'gathering_state' at row 1: UPDATE `gathering_sessions` SET `gathering_state` = 'ready', `updated_at` = '2015-10-31 00:28:36' WHERE `gathering_sessions`.`id` = 120
(0.1ms) ROLLBACK
ActiveRecord::StatementInvalid: Mysql2::Error: Incorrect integer value: 'ready' for column 'gathering_state' at row 1: UPDATE `gathering_sessions` SET `gathering_state` = 'ready', `updated_at` = '2015-10-31 00:28:36' WHERE `gathering_sessions`.`id` = 120
...
from /Users/william/.rvm/gems/ruby-2.2.3/gems/activerecord-4.2.4/lib/active_record/persistence.rb:263:in `update!'
from /Users/william/code/repo/config/initializers/enum_patch.rb:193:in `block (4 levels) in enum'
After doing a little bit of testing, I've realized the problem is not the new code that I've patched in, but the fact that I'm patching in code period. Even when using the same code that is shipped with Rails 4.2.4 (here) I get the same (incorrect) behaviour.
Does anyone have an idea why this is happening and how I can fix it?

Rails n elements before last

In Rails I often do this:
Model.last(5).first
This retrieves element last-5.
Is there a built-in way of doing this?
The more common way is offset()
Model.offset(5).last
Edit (for lazy people):
1.8.7 :001 > User.first.id
=> 1
1.8.7 :002 > User.last.id
=> 143455
1.8.7 :003 > User.offset(5).last.id
=> 143450

Mongoid - how to get second record?

I can do
1.9.3p125 :122 > User.first
=> #<StandardUser _id: 4f849..
and
1.9.3p125 :124 > User.last
and
1.9.3p125 :125 > User.count
=> 5
but I can't find any way to get at the other records (2 thru 4).
User.skip(1).first returns you second document.

Resources