diff --git a/spec/avram/model_spec.cr b/spec/avram/model_spec.cr index 8fa9a8cc2..54b49fdeb 100644 --- a/spec/avram/model_spec.cr +++ b/spec/avram/model_spec.cr @@ -128,6 +128,33 @@ describe Avram::Model do end end + describe "reload?" do + it "can safely reload a model" do + user = UserFactory.create &.name("Original Name") + newly_updated_user = User::SaveOperation.update!(user, name: "Updated Name") + newly_updated_user.name.should eq("Updated Name") + user.name.should eq("Original Name") + + user.reload?.as(User).name.should eq("Updated Name") + + User::DeleteOperation.delete!(user) + + user.reload?.should be_nil + end + + it "can safely reload a model with a yielded query" do + with_lazy_load(enabled: false) do + post = PostFactory.create + + post.reload?(&.preload_tags).as(Post).tags.should be_empty + + Post::DeleteOperation.delete!(post) + + post.reload?(&.preload_tags).should be_nil + end + end + end + it "sets up simple methods for equality" do query = QueryMe::BaseQuery.new.email("foo@bar.com").age(30) diff --git a/src/avram/primary_key_methods.cr b/src/avram/primary_key_methods.cr index d52e65408..cfdb652ec 100644 --- a/src/avram/primary_key_methods.cr +++ b/src/avram/primary_key_methods.cr @@ -66,6 +66,45 @@ module Avram::PrimaryKeyMethods query.find(id) end + # Reload the model with the latest information from the database, if it still + # exists. + # + # This method will return a new model instance with the latest data from the + # database, or `Nil` if the record has been deleted in the meantime. + # + # Example: + # + # ``` + # user = SaveUser.create!(name: "Original") + # + # # ... record is deleted + # + # user.reload? + # # => Nil + # ``` + def reload? : self | Nil + base_query_class.new.id(id).first? + end + + # Same as `reload?` but allows passing a block to customize the query. + # + # This is almost always used to preload additional relationships. + # + # Example: + # + # ``` + # user = SaveUser.create(params) + # + # # ... record is deleted + # + # user = user.reload?(&.preload_comments(CommentQuery.new.preload_article)) + # # => Nil + # ``` + def reload?(&) : self | Nil + query = yield base_query_class.new + query.id(id).first? + end + # For integration with Lucky # This allows an `Avram::Model` to be passed into a Lucky::Action to create a url/path def to_param : String