-
Notifications
You must be signed in to change notification settings - Fork 14
CRUD Operations
In the Mappers section, we learned that you can get at an instance of a mapper using Perpetuity[MyClass]
.
All of our query methods will be on this object.
Each of the examples in this document will be using the following classes:
class Article
def initialize attributes={}
attributes.each { |attr, value| instance_variable_set("@#{attr}", value) }
end
end
class ArticleMapper < Perpetuity::Mapper
map Article
attribute :title
attribute :body
attribute :published_at
attribute :tags
id { title.downcase.gsub(/\W+/, '-') }
end
Objects are inserted using the #insert
method:
article = Article.new(title: 'The Hobbit is a True Story')
Perpetuity[Article].insert article
This will insert an article with the id "The Hobbit is a True Story" and the id "the-hobbit-is-a-true-story" into the Article collection of the database.
The simplest way to retrieve a single object from the database is using the #find
method, which takes an ID:
article = Perpetuity[Article].find(article_id)
Objects are retrieved from the database using the #select
method with a block, similar to an array:
published_articles = Perpetuity[Article].select { |article| article.published_at < Time.now }
Please note that the object yielded to the block is not an actual Article object. You cannot invoke Article instance methods on it. It is a DSL object that allows you to compare attributes of the object to known values for selection. The selection criteria are as follows:
mapper = Perpetuity[Article]
article = mapper.select { |article| article.title == 'The Hobbit is a True Story' }.first
published_articles = mapper.select { |article| article.published_at <= Time.now }
unpublished_articles = mapper.select { |article| article.published_at > Time.now }
lotr_articles = mapper.select { |article| article.body =~ /hobbit/i }
lotr_articles = mapper.select { |article| article.tags.in ['lotr', 'hobbit', 'precious'] }
excluded_articles = mapper.select { |article| article.id.not_equal?(article_id) }
Ideally, you would want to define methods on your mappers for things like this:
class ArticleMapper < Perpetuity::Mapper
map Article
attribute :title
attribute :body
attribute :published_at
def published
select { |article| article.published_at < Time.now }
end
def search(text)
terms = /#{Regexp.escape(text)}/
select { |article| (article.title =~ terms) | (article.body =~ terms) }
end
end
You can update objects with the save
message on the mapper, passing in the object as a parameter:
article.title = 'I Aim to Misbehave'
Perpetuity[Article].save article
That will modify the title (assuming we have a #title=
on the article) and tell Perpetuity to reserialize it and update the existing persisted version of it.
If you have an object that has been persisted to the database, you can delete it with the #delete
message.
Perpetuity[Article].delete draft_article