Differencebetween 'After_Create' and 'After_Save' and When to Use Which

Difference between after_create, after_save and after_commit in rails callbacks

You almost got it right. However there is one major difference between after_commit and after_create or after_save i.e.

In the case of after_create, this will always be before the call to save (or create) returns.

Rails wraps every save inside a transaction and the before/after create callbacks run inside that transaction (a consequence of this is that if an exception is raised in an after_create the save will be rolled back). With after_commit, your code doesn't run until after the outermost transaction was committed. This could be the transaction rails created or one created by you (for example if you wanted to make several changes inside a single transaction). Originally posted here

That also means, that if after_commit raises an exception, then the transaction won't be rolled back.

From M-Dahab's comment:
after_commit would run after create, update and destroy. But, you can use on: option to specify which you are interested in. after_commit :some_method, on: :create or even after_commit :some_method, on: [:create, :destroy] or use a block like after_commit(on: :update) do run_method() end.

What is the difference between `after_create` and `after_save` and when to use which?

after_create only works once - just after the record is first created.

after_save works every time you save the object - even if you're just updating it many years later

So if you want to do this email operation only just the once (and then never again) then use after_create.

If you want to do it every time the object is saved, then do it in after_save

after_create and after_save order

Yes, here's the order:

# (1) before_validation
# (2) before_validation_on_create
# (3) after_validation
# (4) after_validation_on_create
# (5) before_save
# (6) before_create
# (7) after_create
# (8) after_save

Found here:

http://ar.rubyonrails.org/classes/ActiveRecord/Callbacks.html

Rails after_save and after_commit callbacks

You can specify that the callback should only be fired by a certain action with the :on option:

after_commit :do_foo, on: :create
after_commit :do_bar, on: :update
after_commit :do_baz, on: :destroy

after_commit :do_foo_bar, on: [:create, :update]
after_commit :do_bar_baz, on: [:update, :destroy]

How does after_save work when saving an object

In my opinion, if you call save function in a after_save callback, then it will trap into a recursion unless you put a guard at the beginning. like this

class User < AR::Base
after_save :change_url

def change_url
#Check some condition to skip saving
url = "www.johnseena.com"
save #<======= this save will fire the after_save again
end
end

However, apart from putting a guard, you can use update_column also

def change_url
update_column(:url, "www.johnseena.com")
end

In this case it will not fire after_save. However, it will fire after_update. So if you have any update operation on that call back then you are in recursion again :)

What is the difference between .save and .create in Sequelizejs?

As described in the docs http://docs.sequelizejs.com/en/latest/docs/instances/

The method .build() creates a non-persistent instance, which means that the data are not been saved on the database yet, but stored only in the memory, during the execution. When your program stops (server crash, end of the execution or something like that), instances created with .build() will be lost.

This is where .save() do its job. It stores the data of the instance built by the .build() method in the the database.

This approach allows you to manipulate instances in the way you need before storing it in the database.

The .create() method simply .build() and .save() an instance in the same command. It's a convinience for simple cases where you have no need to manipulate instances, allowing you to store the data in the database with a single command. To ilustrate:

This:

User.build({ name: "John" }).save().then(function(newUser){
console.log(newUser.name); // John
// John is now in your db!
}).catch(function(error){
// error
});

is the same as this:

User.create({ name: "John"}).then(function(newUser){
console.log(newUser.name); // John
// John is now in your db!
}).catch(function(error){
// error
});

But you can do something like this:

var user = User.build({ name: "John"}); // nothing in your db yet

user.name = "Doe"; // still, nothing on your db

user.save().then(function(newUser){
console.log(newUser.name); // Doe
// Doe is now in your db!
}).catch(function(error){
// error
});

Basically, .build() and .save() gives you the ability to modify an instance after it has been instanciated, but before you store it's data in the database.

Rails 3: Should I explicitly save an object in an after_create callback?

This looks like a task for before_create to me. If you have to save in your after_* callback, you probably meant to use a before_* callback instead.

In before_create you wouldn't have to call save, as the save happens after the callback code runs for you.

And rather than saving then querying to see if you get 2 or more objects returns, you should be querying for one object that will clash before you save.

In psuedo code, what you have now:

after creation
now that I'm saved, find all tasks in my room and at my time
did I find more than one?
Am I the first one?
yes: add note about another task, then save again
no: everything is fine, no need to re-save any edits

What you should have:

before creation
is there at least 1 task in this room at the same time?
yes: add note about another task
no: everything is fine, allow saving without modification

Something more like this:

before_create :check_room_schedule
def check_room_schedule
conflicting_task = Task.for_date(self.day)
.for_room(self.room)
.where(begin: self.begin) # unsure what logic you need here...
.first
if conflicting_task
self.notes =
"There is another meeting in this room beginning at #{conflicting_task.begin.strftime("%I:%M%P")}."
end
end

after_create with multiple methods?

No need to surround the methods in array. Simply use:

after_create :do_this, :and_then_this

Bonus Information:
If a before_* callback returns false, all the later callbacks and the associated action are cancelled. If an after_* callback returns false, all the later callbacks are cancelled. Callbacks are generally run in the order they are defined, with the exception of callbacks defined as methods on the model, which are called last.

How to determine if a record is just created or updated in after_save

I was looking to use this for an after_save callback.

A simpler solution is to use id_changed? (since it won't change on update) or even created_at_changed? if timestamp columns are present.

Update: As @mitsy points out, if this check is needed outside of callbacks then use id_previously_changed?. See docs.



Related Topics



Leave a reply



Submit