-
-
Save garybernhardt/4534954 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# I don't really see any services here. What I see is: | |
# - Normal HTTP boundary stuff (params flash, redirect). | |
# - Model creation and retrieval. | |
# - Warden manipulation, which is an odd done but smells like boundary. | |
# | |
# I left all of the HTTP boundary stuff in the controller (and only the | |
# controller). I moved the model creation/retrieval into simple class methods | |
# in the models. I moved the warden manipulation stuff into | |
# ApplicationController (with caveats that I'll discuss inline). | |
# | |
# Commentary on each class follows: | |
# Commentary: | |
# | |
# I simplified the `new` action by pushing the new-account-with-owner | |
# relationship down to the model. Depending on the domain, it may make sense | |
# to run build_owner on all new objects; it's not clear. (This is also true of | |
# all of the model changes that follow. Some or all of them may make more | |
# sense if enforced all of the time--either after-the-fact via foreign keys | |
# and validations, or that plus before-the-fact by hooking into object | |
# creation. | |
# | |
# The AccountsController unpacks the params for Account, but lets Account | |
# deal with the details of manipulating the database and model relationships. | |
# I don't know what the proper name for the create_with_owner method is, | |
# since I don't know the domain. | |
# | |
# forced_authentication hides warden; details later. | |
module Subscribem | |
class AccountsController < ApplicationController | |
def new | |
@account = Account.new_with_owner | |
end | |
def create | |
account = Account.create_with_owner(params[:account]) | |
force_authentication(account.owner.id, account.id) | |
flash[:success] = "Your account has been successfully created." | |
redirect_to subscribem.root_url(:subdomain => account.subdomain) | |
end | |
end | |
end | |
# Commentary: | |
# | |
# Same story as the AccountsController, really. I pull the model creation out | |
# into a method (again, I don't know its proper name). | |
module Subscribem | |
class Account::UsersController < ApplicationController | |
def new | |
@user = Subscribem::User.new | |
end | |
def create | |
user = User.create_within_account(account, params[:user]) | |
force_authentication(user, account) | |
flash[:success] = "You have signed up successfully." | |
redirect_to root_path | |
end | |
end | |
end | |
# Commentary: | |
# | |
# I'm conflicted about putting auth in ApplicationController vs. moving it to | |
# a module or another object; I really don't know which of the three I | |
# prefer. The nice thing about putting it here (or in a module) is that | |
# controllers don't have to be digging around in the rack env to pull the | |
# warden object out. If this were another application concern--one that | |
# didn't cut across the entire application like authentication does--then I | |
# wouldn't do this. If ApplicationController hit 50 lines or so, I'd probably | |
# pull things out. | |
class ApplicationController | |
def force_authentication(user, account) | |
env['warden'].set_user(user, :scope => :user) | |
env['warden'].set_user(account, :scope => :account) | |
end | |
end | |
# Commentary: | |
# | |
# The Account model encapsulates manipulation of accounts, including creating | |
# them. | |
class Account < ActiveRecord::BallAndChain | |
def self.new_with_owner | |
account = Subscribem::Account.new | |
account.build_owner | |
account | |
end | |
def self.create_with_owner(params) | |
account = create(params) | |
account.users << account.owner | |
account.create_schema | |
account | |
end | |
end | |
# Commentary: | |
# | |
# Same as Account: it encapsulates creation. | |
class User < ActiveRecord::BallAndChain | |
def self.create_within_account(account, params) | |
user = Subscribem::User.create(params[:user]) | |
account.users << user | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment