Using a transaction in a Ruby on Rails method

I love Ruby On Rails and every day I learn and improve my skills. I am currently working on an application that is used by multiple clients and I want to refactor my code so that I can be confident in the quality of my code.

I am struggling with how I should implement exception handling and use transactions. I have a controller that needs to create and update three objects. To simplify my situation.

in my controller:

def update
  @user.change_value_x  #(1) effects Model 'User'
  if condition == y 
    @user.create_coupon #(2) effects Model 'Coupon' via Model 'User' 
  end
  create_a_history_item #(3) effect Model 'History' 
end

      

The first (1) and second method (2) are located in the user model, and the third method (3) is also used by other controllers and is located in a module in the / lib directory. All methods of updating / saving / creating database items.

And if one of the actions fails, all database actions should bounce back and give feedback on the problem.

I know that "transaction" is a good solution for this, and I also blush in various messages that a transaction should not be used in the controller.
Question : Why is this?

So, I think this code is inappropriate for implementing a transaction.

def update
  ActiveRecord::Base.transaction do
    @user.change_value_x  #(1) effects Model 'User'
    if condition == y 
      @user.create_coupon #(2) effects Model 'Coupon' via Model 'User' 
    end
    create_a_history_item #(3) effect Model 'History'
  end
  rescue
  #some code that gives feedback to user about the problem
end

      

What is the best / correct way to handle this?

+3


source to share


2 answers


Transactions should be supported at the model level as much as possible, as they are associated with the model and not with the logic. A transaction in a controller is like an SQL query in a controller: it feels out of place.



If you don't have anything wrong with your solution, but maybe methods on your models (or service layer) will help keep your controller clean? For example, methods such as User#update_x_and_create_coupon

and User#update_x_and_create_history_item

.

+4


source


You can use Transaction

in your controller if you like, but this is bad practice, but if you want to do this just wrap it User.transaction do

.



The reason this is bad practice is because it does not share the concern according to the MVC paradigm. The controller doesn't have to care about your implementation of persistence. A better approach would be to add a method to User

.

+2


source







All Articles