I have two controllers one is Payments and one is Transactions, I need to call the create method of transactions inside the create method of payments. So that each time I create a payment a transaction is automatically created. How should I approach this?
module Api class PaymentsController < ApplicationController before_action :set_payment, only: %i[ show update destroy ] def index @payments = Payment.all render json: @payments end def show render json: @payment end def create @payment = Payment.new(payment_params) if @payment.save render json: 'Payment Is Made sucessfully'.to_json, status: :ok else render json: @payment.errors, status: :unprocessable_entity end end private def payment_params params.permit(:currency, :amount, :payment_type, :payment_address) end end end
module Api class TransactionsController < ApplicationController before_action :set_transaction, only: %i[show update destroy] def index @transactions = Transaction.all render json: @transactions end def show render json: @transaction end # POST /transactions def create @transaction = Transaction.new(transaction_params) if @transaction.save render json: @transaction, status: :created, location: @transaction else render json: @transaction.errors,status::unprocessable_entity end end private def transaction_params params.permit(:transaction_type, :bank_name, :debit, :credit, :total_amount) end end end
CodePudding user response:
First to note, MVC is just a convention or good way to organize your code.
You can simply do:
def create
@transaction = Transaction.new(transaction_params)
# You'll have to figure out how to get the params in here - maybe they are all derived from the transaction?
@payment = Payment.new()
@payment.save
# handle payment error here too like below
if @transaction.save
render json: @transaction, status: :created, location: @transaction
else
render json: @transaction.errors,status::unprocessable_entity
end
end
However, this doesn't present itself well towards reusable code.
We have 2 options - put it into the model or introduce a service.
In the transaction model, we can create a function like:
class Transaction
...
def self.create_with_payment(params)
Transaction.create(params)
Payment.create(params)
# do whatever here to create and associate these
end
or we can introduce a service object:
class TransactionPaymentCreator
def call(params)
Transaction.create(params)
Payment.create(params)
end
end
You can then call this in your controller:
def create
service = TransactionPaymentCreator.new
service.call
end
I'm leaving out a lot of detail like how to set these things up - but I hope to convey to you the general details - you have 3 options on how to make this work.
Here is a good article and resource on reading more for service objects if you decide to go that route:
https://www.honeybadger.io/blog/refactor-ruby-rails-service-object/
CodePudding user response:
My approach would be to make a callback on your Payment model:
# payment.rb
after_create :create_transaction
def create_transaction
Transaction.create(payment_id: id) # or whatever params you need in the transaction
end