Most of my apps these days that are pure html with a backend are written in Ruby on Rails and use the Devise engine to handle password and account creation type things.
For this example we will be assume a few things
- You have rails 4+ and Devise Setup
- Devise routes are setting the registration controller as your custom controller.
- models are User and Account
- User belongs_to Account (so User has an account_id)
- User responds to set_admin to deal with however admin is setup.
I was reading through the source the other day and saw this block option in the RegistrationsController for devise
[ruby]
class Devise::RegistrationsController
# POST /resource
def create
build_resource(sign_up_params)
resource.save
yield resource if block_given?
#other devise stuff
respond_with resource
end
end
[/ruby]
[ruby]yield resource if block_given[/ruby]
means that we can pass some code in as a block (which is just an anonymous function) that will receive the resource as a parameter.
In your resources controller you can override like this
[ruby]
class RegistrationsController < Devise::RegistrationsController
def create
super {|user| user.create_account }
end
end
[/ruby]
So with this code, super sends the block up the chain. So the result is that when we get to the yield resource, the resources receives the message ‘create_account’.
This is great, now we are able to delegate all of our registration logic to devise. But wait, what if we now want to set the user as admin on the account and make sure that it is all wrapped up in a transaction? That is easy, just expand the block.
[ruby]
def create
ActiveRecord::Base.transaction do
super do |user|
user.create_account
user.set_admin
end
end
end
[/ruby]
At this point, we have fulfilled the feature that we create the account along with the user and set that user as the admin on the account, so ship the feature!