Last active
May 24, 2023 11:04
-
-
Save bookwyrm/1424056e732647898414 to your computer and use it in GitHub Desktop.
Cleaning up Rails app signup with Devise and Reform
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
class Account < ActiveRecord::Base | |
has_many :users | |
end |
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
# POST /resource | |
def create | |
build_resource(sign_up_params) | |
resource_saved = resource.save | |
yield resource if block_given? | |
if resource_saved | |
# Do saved stuff... | |
else | |
# Re-render to fix | |
end | |
end |
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
<%# app/views/devise/registrations/new.html.erb %> | |
<h2>Sign up</h2> | |
<%= simple_form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %> | |
<%= f.error_notification %> | |
<div class="form-inputs"> | |
<%= f.input :email, required: true, autofocus: true %> | |
<%= f.input :company_name, required: true %> | |
<%= f.input :password, required: true, hint: ("#{@minimum_password_length} characters minimum" if @validatable) %> | |
<%= f.input :password_confirmation, required: true %> | |
</div> | |
<div class="form-actions"> | |
<%= f.button :submit, "Sign up" %> | |
</div> | |
<% end %> | |
<%= render "devise/shared/links" %> |
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
# app/forms/registration_form.rb | |
class RegistrationForm < Reform::Form | |
include Composition | |
property :company_name, on: :account | |
property :email, on: :user | |
property :password, on: :user | |
property :password_confirmation, on: :user, empty: true | |
model :user | |
validates :email, presence: true | |
validates :password, presence: true, confirmation: true | |
validates :password, length: { minimum: 8 } | |
validates :company_name, presence: true | |
def active_for_authentication? | |
true | |
end | |
def authenticatable_salt | |
end | |
def save | |
return false unless valid? | |
sync | |
user = model[:user] | |
user.account = model[:account] | |
user.save | |
end | |
end |
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
# app/controllers/registrations_controller.rb | |
class RegistrationsController < Devise::RegistrationsController | |
def create | |
configure_permitted_parameters | |
super | |
end | |
protected | |
def configure_permitted_parameters | |
devise_parameter_sanitizer.for(:sign_up) << :company_name | |
end | |
def build_resource(hash = nil) | |
self.resource = registration_form = RegistrationForm.new(user: User.new, account: Account.new) | |
unless hash.nil? || hash.length == 0 | |
self.resource.validate hash | |
end | |
end | |
def after_sign_up_path_for(resource) | |
root_path | |
end | |
end |
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
# spec/controllers/registrations_controller_spec.rb | |
require 'rails_helper' | |
RSpec.describe RegistrationsController, type: :controller do | |
before :each do | |
@request.env['devise.mapping'] = Devise.mappings[:user] | |
end | |
describe "POST #create" do | |
let(:post_params) { attributes_for(:user).merge(attributes_for(:account)) } | |
it "Creates a user" do | |
expect { | |
post :create, user: post_params | |
}.to change(User, :count).by(1) | |
end | |
it "Creates an account" do | |
expect { | |
post :create, user: post_params | |
}.to change(Account, :count).by(1) | |
end | |
it "Associates the user with the account" do | |
post :create, user: post_params | |
user = User.last | |
account = Account.last | |
expect(user.account).to eq(account) | |
end | |
end | |
end |
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
# config/routes.rb | |
Rails.application.routes.draw do | |
devise_for :users, controllers: { | |
registrations: 'registrations', | |
} | |
root 'welcome#index' | |
end |
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
# app/models/user.rb | |
class User < ActiveRecord::Base | |
# Include default devise modules. Others available are: | |
# :confirmable, :lockable, :timeoutable and :omniauthable | |
devise :database_authenticatable, :registerable, | |
:recoverable, :rememberable, :trackable, :validatable | |
belongs_to :account | |
end |
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
# spec/features/user_registrations_spec.rb | |
require 'rails_helper' | |
describe 'User registration' do | |
let(:user_email) { Faker::Internet.email } | |
let(:user_password) { Faker::Internet.password(8) } | |
let(:company_name) { Faker::Company.name } | |
before :each do | |
visit new_user_registration_path | |
fill_in 'user_company_name', with: company_name | |
fill_in 'user_email', with: user_email | |
fill_in 'user_password', with: user_password | |
fill_in 'user_password_confirmation', with: user_password | |
click_button 'Sign up' | |
end | |
it "lets the user log in" do | |
visit new_user_session_path | |
fill_in 'user_email', with: user_email | |
fill_in 'user_password', with: user_password | |
click_button 'Log in' | |
expect(page).to have_content("Welcome") | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Isn't the Devise::RegistrationsController does a resource.active_for_authentication? instead of save?