Reputation: 89
I am trying to set the attribute flag to false like this:
Model.where(:s_id => s_id).flag = false
(I have s_id) but it didn't work and this one didn't work too :
Model.find(s_id).flag = false
Any help??
Upvotes: 1
Views: 618
Reputation: 2466
While theTRON’s answer is correct, another part of the problem is that Model.find(id)
returns the instance of Model
with the given id
(or throws an exception if there isn’t one), so immediately setting an attribute works (but isn’t persisted without doing something to do so as theTRON points out), while Model.where(...)
returns a Criteria
. For example:
$ rails c
[1] pry(main)> s_id="..."
[2] pry(main)> User.find(s_id)
=> #<User _id: BSON::ObjectId('...'), name: "User 1">
[3] pry(main)> User.find(s_id).name = "Some other user"
=> "Some other user"
User.find
is returning a User
instance, so you can set attributes on it. However:
[4] pry(main)> User.where(_id: s_id)
=> #<Mongoid::Criteria
selector: {"_id"=>BSON::ObjectId('...')}
options: {}
class: User
embedded: false>
[5] pry(main)> User.where(_id: s_id).name = "Someone else"
NoMethodError: undefined method `name=' for #<Mongoid::Criteria:0x00007feb9c04ec48>
User.where
is returning a Criteria
which doesn’t have a name attribute. Instead you can do something like:
[5] pry(main)> User.where(_id: s_id).first.name = "Someone else"
=> "Someone else"
That’s because Criteria.first
returns the first instance. Once you have an instance, you can again set attributes.
Of course that’s just setting the attribute in memory, you still need to persist it (or set it in such a way it’s persisted automatically, theTRON’s answer covers that).
I’ve used the rails console just because it’s an easy way to demonstrate what’s going on, but the same thing goes on in regular ruby code.
Upvotes: 0
Reputation: 9659
The problem with your code is that you've changed the flag
attribute, but not saved the document afterwards. There's lots of different ways you can handle this, most of which are detailed in the persistence section of the documentation.
If you're only updating one model, and you have the ID, you can use the update_attribute
method:
Model.find(id).update_attribute(:flag, false)
The update_attribute
method updates the attribute (obviously) but then also calls save
on the document, persisting the changes in the database. You could achieve this the long way by doing:
m = Model.find(id)
m.flag = false
m.save
Alternatively, if you're wanting to update a set of models, from a criteria (like the where
method), you can use update_all
:
Model.where(:flag => true).update_all(:flag => false)
Upvotes: 2