Build Robust & Production Quality Applications - Lesson 8: Beyond MVC - Domain Objects
12 Jul 2015Domain Objects
Domain Objects are objects that are within the domain object model. Not all of them inherit from active record though, often times they do not always map to database tables.
For important attributes, it may be worth it to create a seperate domain object rather than calling an object to access that attribute.
#apps/controllers/todos_controller.rb
def create
@todo = Todo.new(params[:todo)]
if @todo.save_with_tags
user.created_at < Date.new(2013, 1, 1) || user.plan.premium?
new_credit_balance = current_user.current_credit_balance - 1
else
new_credit_balance = current_user.current_credit_balance - 2
end
current_user.current_credit_balance = new_credit_balance
current_user.save
if new_credit_balance < 0
AppMailer.notify.insufficient_funds
elsif current_user.current_credit_balance < 10
AppMailer.notify_low_balance
end
redirect_to root_path
else
render :new
end
Let's create a domain called Credit:
#app/models/credit.rb
class Credit
attr_accessor :credit_balance, :user
def initialize(user)
@credit_balance = user.current_credit_balance
@user = user
end
def -(number)
credit_balance = credit_balance - number
end
def save
user.current_credit_balance = credit_balance
user.save
end
def depleted?
credit_balance < 0
end
def low_balance?
credit_balance < 10
end
end
Now let's update the Todos Controller:
#apps/controllers/todos_controller.rb
def create
@todo = Todo.new(params[:todo)]
credit = Credit.new(current_user)
if @todo.save_with_tags
if UserLevelPoicy.new(ccurent_user).premium?
credit = credit - 1
else
credit = credit - 2
end
credit.save
if credit.depleted? < 0
AppMailer.notify.insufficient_funds
elsif credit.low_balance?
AppMailer.notify_low_balance
end
redirect_to root_path
else
render :new
end