-
Notifications
You must be signed in to change notification settings - Fork 1
Builder
Builder can be useful when you want to collect and use some complex data.
Let's imagine we don't use any ORM in a project and want to use pure SQL queries to control all processes. For this we can use a builder (DONT USE THIS CODE IN PRODUCTION! THIS IS JUST EXAMPLE TO UNDERSTAND HOW YOU CAN USE BUILDER).
First, create a new builder:
rails g builder sql
It will create app/builders/sql_builder.rb file.
Let's imagine we need only two operations with database: select and insert. We will not update or delete data. Here is the code:
# app/builders/sql_builder.rb
class SqlBuilder < Methodist::Builder
OPERATIONS = [SELECT_OPERATION INSERT]
field :operation, ->(val) { val.present? && OPERATIONS.include?(val) }
field :source, -> (val) { val.present? }
field :columns
field :where
field :values
field :order
field :limit
def result_query
raise 'Invalid data in the builder' unless valid?
send("#{operation.downcase}_query")
end
private
def select_query
str_query = "SELECT"
str_query += if columns ? " #{columns}" : " *"
str_query += " FROM #{source}"
str_query += " WHERE #{where}" if where
str_query += " ORDER BY #{order}" if order
str_query += " LIMIT(#{limit})" if order
str_query
end
def insert_query
str_query = "INSERT INTO"
str_query += " (#{*columns})"
str_query += " VALUES (#{*values})"
end
def
endIn the #field method we define the field attribute. You can list all builder attributes with instance_of_builder.attributes. The second argument in the #field is a proc with validation. When procs return true for all attriubutes then #valid? also returns true.
Now we can use our builder:
query = SqlBuilder.new
query.operation = 'SELECT'
query.source = 'cars'
query.where = 'color = red'
query.order = 'created_at ASC'
query.limit = '2'
query.result_query # => "SELECT * FROM cars WHERE color = red ORDER BY created_at ASC LIMIT(2)"
query.columns = ["id", "producer", "color", "created_at"]
query.result_query # => "SELECT id, producer, color, created FROM cars WHERE color = red ORDER BY created_at ASC LIMIT(2)
query.valid? #=> true
query.operation = 'FailedOperation'
query.valid? #=> false