Is save method mandatory in rails? - ruby

Model.find(ids).each { |model| model.is_active = false } unless ids.empty?
Here, is model.save method necessary or not ? Because without that also, it's working.
Column is defined like this
t.integer :is_active, limit: 1

The short answer to your question is: Yes.
Running model.is_active = false, by itself, will not persist the change in the database. Try re-fetching the database record after running model.is_active = false, and you'll see that the value has not actually changed; you also need to run model.save to do that.
However, for scenarios like this (assuming you want to immediately save the change to the record!) there's a more concise way of saving the data, instead of running two commands:
model.update_attribute(:is_active, false)
This will update the value in the database, if validations pass, and also run any callbacks (e.g. after_save).
If you want to update the value without running validations and callbacks (which is typically faster, but more "dangerous") then you can instead use:
model.update_column(:is_active, false)

Related

Aurelia Validation Result Is Both True And False

I'm using Aurelia-validation, and I've created a validation-controller that can on demand run validate( object: myObj, propertyName: "myProp", rules : MyRules)
Documentation:
https://aurelia.io/docs/plugins/validation#validation-controller
For some reason I get, what I can only describe as a conflict, in my validation result object. The only rule I validate on is "required()", and it returns true. However, the result object as a whole returns false. Why is that?
Take a look (using my real data):
Take a close look to your "valid" type. One is Boolean and the other is a String! Check if you can take control of that!
I suppose it has something to do with chrome dev tools, because it seem to happen only when I inspect it while it's running, and not when I console.log() the values and let it finish, Then they correspond to each other. Oh well!

Mongoid - set a field to true for at least one document

I want there always to be at least one document in database which has a field titled "selected" set to true. How do I do that? Most probably I have to use callbacks, but which one: before (or after) _create, _upsert, _update?
And how can I ensure that it will be set to true whatever operation executes: create, update, upsert...? I guess that would not be right to create a callback for each of them.
after_save always runs after create & update
so you could do:
after_save do |your_class|
your_class.update_column(:selected, true) unless YourClass.where(selected: true).exists?
end
NB./ update_column should not fire the after_save again!

Why can't I check ActiveRecord validations in the console?

I'm learning RoR at the moment, and I think I must be misunderstanding something.
I have an ActiveRecord class call User, with simple validations on :name and :email such as presence: true, length: { maximum: 15 }, etc. I thought I'd check the validations in the console. I go into rails console (development env), and create a new instance with a name that is too long, such as
user_instance = User.new (name:"aaaaabbbbbcccccddddd", email:"").
The validation doesn't throw up any errors. When I try user_instance.save, the record won't write to the DB, so it's obviously working fine at that stage. What am I doing wrong?
When you want to get an exception raised on record saving, use save! instead of save (same with update/update!, create/create!).
With save you won't have an exception raised if there are validation errors, it will just return false. You can also check if there are errors on an instance with user_instance.valid? and get the errors with user_instance.errors.
See When Does Validation Happen?.
the validation won't throw errors if you try to set invalid data on your model, however the save will fail.
if you wanna check out if the validation is working correctly, just check user.valid? and it should return false
after calling valid?, you can check user.errors for the specific errors set on your model.

Cannot access session array from view in Rails 3.1

So this one has me stumped; hopefully a kind soul can help me out. As part of logic to display certain buttons for users who have performed an action, I store the id of the object they manipulated in a session array called "prayed_for". (The unique part of this problem is that it deals with sessions and not an array persisted in a database.) In the show action of my controller, I evaluate whether of not the current id of the entry being requested is present in the session array "prayed_for". I assign this boolean value to the session variable #already_prayed_for. Below is the logic for that:
#already_prayed_for = (session[:prayed_for] ||= []).include? params[:id]
But here's the problem: I cannot evaluate this in my partial. For example if I attempt to evaluate the following (in HAML), where "entry" is a variable representing the entry at hand and "id" is it's id, which should be stored in the session "prayed_for" variable, it will always evaluate to false:
-if (session[:prayed_for] ||= []).include? entry.id
I've come to the conclusion that I may be evaluating something wrong in my partial when evaluating whether or not an id is present in a session array. Additionally this same concept worked perfectly in a controller action (but I can't use that solution this time around, it has to be evaluated in the partial) but it also failed in the ApplicationHelper. Any help in resolving this problem is much appreciated!
UPDATE:
Here's the code where I set the session in another action:
if #entry.save
(session[:prayed_for] ||= []) << params[:id]
end
params[:id] may be a String, while entry.id is a Fixnum. Verify that the objects you're comparing (via include?) are of the same type.
You might want to make a helper out of the logic you're using, for example:
def already_prayed_for?(entry_id)
(session[:prayed_for] ||= []).include? entry_id.to_i
end

Runtime changing model with mongodb/mongoid

I've to add several fields in a mongoid model, I know there is not migration with MongoDB but if I go on without dropping the DB, making rails to "regenerate" the DB entirely, it doesn't display or use the new fields at all !
What's the best way to go here ? Is there something softer than drop/reopen mongodb ?
Thanks in advance
luca
In general it should be possible to update old documents with the new fields at runtime. There is no need for migrations in MongoDB.
You maybe want to write rake tasks to update your old documents with the new fields and default values.
You could find out these documents by checking those new fields which have per default a nil value.
Update
Easy style:
If you define a new field with a default value, this value should always be used as long as you set a new one:
app/models/my_model.rb
class MyModel
include Mongoid::Document
field :name, type: String
field :data, type: String
# NEW FIELD
field :note, type: String, default: "no note given so far!"
end
If you query your database you should get your default value for documents which haven't this field before your extension:
(rails console)
MyModel.first
#=> #<MyModel …other fields…, note: "no note given so far!">
I tested this with a fresh rails stack with a current mongoid on Ruby 1.9.2 - should work with other stacks, too.
More complicated/complex style:
If you didn't set a default value, you'll get nil for this new field.
app/models/my_model.rb
class MyModel
include Mongoid::Document
field :name, type: String
field :data, type: String
# NEW FIELD
field :note, type: String
end
(rails console)
MyModel.first
#=> #<MyModel …other fields…, note: nil>
Then you could set up a rake task and migration file like in this example:
lib/tasks/my_model_migration.rake:
namespace :mymodel do
desc "MyModel migration task"
task :migrate => :environment do
require "./db/migrate.rb"
end
end
db/migrate.rb:
olds = MyModel.where(note: nil)
# Enumerator of documents without a valid :note field (= nil)
olds.each do |doc|
doc.note = "(migration) no note given yet"
# or whatever your desired default value should be
doc.save! rescue puts "Could not modify doc #{doc.id}/#{doc.name}"
# the rescue is only a failsafe statement if something goes wrong
end
Run this migration with rake mymodel:migrate.
This is only a starting point and you can extend this to a full mongoid migration engine.
The task :migrate => :environment do … is necessary, otherwise rake won't load models.
It is a little ridiculous to say that you don't need migrations with mongodb or mongoid. Any sophisticated app needs to be refactored from time to time and that can mean pulling fields out of disparate documents into a new one.
Writing one off rake tasks is way less convenient and error prone than having migrations be part of your deploy script so that it always gets run on every environment.
https://github.com/adacosta/mongoid_rails_migrations brings AR style migrations to mongoid.
You might need them less often, but you will certainly need them as an app grows.
Below is a nice code example for data migration script with mongoid and the ruby mongo driver - to be used when your updated model no longer match production data.
http://pivotallabs.com/users/lee/blog/articles/1548-mongoid-migrations-using-the-mongo-driver
I whish we would stop using "no migrations with mongoid" as slogan. It'll turn people to MongoDB for the wrong reasons, and it's only partially true. No schema, true, but data still needs to be maintained, which IMO is harder with MongoDB than RDBMs. There are other, great reasons for choosing MongoDB and it depends on your problem.

Resources