简体   繁体   中英

Rails - how do I avoid having to trigger the create action in one controller from the create action in another controller

Forgive a basic question here.

From reading around, I understand it's not best practice to trigger the create action of a controller from another - I'm looking for advice on how I should be organizing my code in the following situation:

I have two controllers: cases and notifications.

When a new case is created I want it to also create a new notification.

The notification create action creates a new instance in it's model, and sends an email.

Am I right to think that I shouldn't just be calling Notification#create from my cases controller? Should I be extracting this to a helper or module? If so, what would it look like? The other roughly similar posts on this topic don't elaborate.

Thank you.

Since create is a POST method, I don't think there is a way for calling create of notifications controller from cases controller. My suggestion would be to move the creation of notification instance and the sending mail logic to the before save of your case model. This would create a notification each time a case is created and would also take care of the mail sending mechanism. Since this is a part of your business requirement it is better to move the business logic into your model.

This logic should be in your models. Good solution is to use ActiveRecord callbacks for it.

# app/models/case.rb
class Case < ActiveRecord:Base
  after_create :create_notification

private        # <--- bottom of your model
  def create_notification
    Notification.create!(some_options_for_notification)
  end
end

# app/models/notification.rb
class Notification < ActiveRecord:Base
  after_create :send_notification

def send(opts)
  ...          # <--- some logic to send notification here
end


private        # <--- bottom of your model
  def send_notification
    send(some_options_for_sending)
  end
end

As one of options you can use rails observers for creating notification http://api.rubyonrails.org/classes/ActiveRecord/Observer.html

There are few differences between observers and callbacks, for example observers can't cancel any model action, but in your case I think there is no matter what to use.

But observers also used to adhere to the Single Responsibility principle.

Example

class CaseObserver < ActiveRecord::Observer
 def after_create(case)
    #create notification
 end
end

should be saved to /app/models/case_observer.rb.

in your config/application.rb

config.active_record.observers = :case_observer

You just need to write Notification.create in your case controllers action, that's it.

You can write as much of code, create as much of model in your controller action as much you want.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM