-
-
Save okliv/9299f5f94c147e3525b4dca5d6f1c510 to your computer and use it in GitHub Desktop.
Rails template example to generate a new ruby on rails project with a professionalized sign-in, sessions, plans, rolse, multi-tenant, jquery, bootstrap 3 (flat design) ...
This file contains hidden or 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
# add gems | |
gem 'whenever' | |
gem 'kaminari' | |
gem 'hpricot' | |
gem 'ruby_parser' | |
gem 'jquery-rails' | |
gem "jquery-ui-rails" | |
gem 'bcrypt-ruby', '~> 3.0.0' | |
gem "rspec-rails", :group => [ :development, :test ] | |
gem "ffaker", :group => :test | |
gem "autotest", :group => :test | |
gem 'anjlab-bootstrap-rails', :require => 'bootstrap-rails', | |
:github => 'anjlab/bootstrap-rails', | |
:branch => '3.0.0' | |
# install gems | |
run 'bundle install' | |
# Templates | |
file 'app/views/shared/_errors.html.erb', <<-CODE | |
<% if object.errors.any? %> | |
<div class="alert alert-error"> | |
<a class="close" data-dismiss="alert">×</a> | |
<ul> | |
<% object.errors.full_messages.each do |msg| %> | |
<%= content_tag :li, msg %> | |
<% end %> | |
</ul> | |
</div> | |
<% end %> | |
CODE | |
#create db | |
rake "db:create" | |
#generate 'simple_form:install' | |
generate 'rspec:install' | |
#email configuration | |
inject_into_file "config/environments/development.rb", :after => "config.assets.debug = true" do | |
<<-eos | |
#please authenticate into www.mandrillapp.com to get credentials | |
config.action_mailer.delivery_method = :smtp | |
config.action_mailer.smtp_settings = { | |
address:"smtp.mandrillapp.com", | |
port:587, | |
authentication: "plain", | |
user_name:"{mandrillapp_mail_login}", | |
password:"{mandrillapp_password}", | |
enable_starttls_auto: true | |
} | |
eos | |
end | |
# rake migration | |
rake "db:migrate" | |
# remove defaults files | |
remove_file 'public/index.html' | |
remove_file 'rm app/assets/images/rails.png' | |
# add database.yml to .gitignore | |
run "echo 'config/database.yml' >> .gitignore" | |
# generate create pages and scaffolds | |
run "rails generate controller pages index home about contact help" | |
run "rails generate scaffold Users email first_name laste_name password:digest tenant_id:integer role_id:integer" | |
run "rails g scaffold tenants company url plan_id:integer" | |
run "rails g scaffold roles name" | |
run "rails g scaffold plans name period:integer max_members:integer" | |
run "rails g controller sessions new creat destroy" | |
# Route | |
route "root to: 'pages#index'" | |
route "controller :sessions do | |
get 'login' => :new | |
post 'login' => :create | |
delete 'logout' => :destroy | |
end" | |
route "controller :users do | |
get 'addnewuser' => :addnewuser | |
get 'addnewusercreate' => :addnewusercreate | |
post 'addnewusercreate' => :addnewusercreate | |
end" | |
route "controller :pages do | |
get 'chooseaplan' => :chooseaplan | |
post 'createaplan' => :createaplan | |
end" | |
route "get 'home' => 'pages#home' | |
get 'about' => 'pages#about' | |
get 'contact_us' => 'pages#contact' | |
get 'help' => 'pages/help'" | |
# add nav bars links | |
inject_into_file "app/views/layouts/application.html.erb", :after => '<body>' do | |
<<-EOS | |
<%= render "shared/nav" %> | |
<div class="container"> | |
<div class="row"> | |
<div class="col-md-12"> | |
<%= render "shared/subnav" %> | |
</div> | |
</div> | |
<div class="row"> | |
<div class="col-md-12"> | |
<%= render "shared/notice" %> | |
</div> | |
</div> | |
<br> | |
<div class="row"> | |
<div class="col-md-8"> | |
<%= yield %> | |
</div> | |
<div class="col-md-4"> | |
<%= yield :right %> | |
</div> | |
</div> | |
</div> | |
<br> | |
EOS | |
end | |
#create navs files | |
file 'app/views/shared/_navs.html.erb', <<-CODE | |
<nav class="navbar navbar-default" role="navigation"> | |
<!-- Brand and toggle get grouped for better mobile display --> | |
<div class="navbar-header"> | |
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1"> | |
<span class="sr-only">Toggle navigation</span> | |
<span class="icon-bar"></span> | |
<span class="icon-bar"></span> | |
<span class="icon-bar"></span> | |
</button> | |
<a class="navbar-brand" href="#">Brand</a> | |
</div> | |
<!-- Collect the nav links, forms, and other content for toggling --> | |
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1"> | |
<ul class="nav navbar-nav"> | |
<li class="active"><%= link_to "Index", root_url %></li> | |
<li><%= link_to "Home", home_url %></li> | |
<li><%= link_to "about", about_url %></li> | |
<li><%= link_to "contact us", contactus_url %></li> | |
</ul> | |
<form class="navbar-form navbar-left" role="search"> | |
<div class="form-group"> | |
<input type="text" class="form-control" placeholder="Search"> | |
</div> | |
<button type="submit" class="btn btn-default">Submit</button> | |
</form> | |
<ul class="nav navbar-nav navbar-right"> | |
<% if session[:user_id] %> | |
<li class="dropdown"> | |
<a href="#" class="dropdown-toggle" data-toggle="dropdown">Hi! <%= session[:user_name] %><b class="caret"></b></a> | |
<ul class="dropdown-menu"> | |
<li><%= link_to "Edit", edit_user_url(session[:user_id]) %></li> | |
<li><%= link_to "Users", users_url %></li> | |
<li class="divider"></li> | |
<li><%= link_to "Log-Out", logout_url, method: :delete %></li> | |
</ul> | |
</li> | |
<% else %> | |
<li><%= link_to "Sign-in", login_url %></li> | |
<li><%= link_to "Sign-up", new_user_url %></li> | |
<% end %> | |
</ul> | |
</div><!-- /.navbar-collapse --> | |
</nav> | |
CODE | |
file 'app/views/shared/_notice.html.erb', <<-CODE | |
<% flash.each do |name, msg| %> | |
<% if msg.is_a?(String) %> | |
<div class="alert alert-<%= name == :notice ? 'success' : name == :warning ? 'warning' : 'danger' %>"> | |
<a class="close" data-dismiss="alert">×</a> | |
<%= content_tag :div, msg, :id => "flash_#{name}" %> | |
</div> | |
<% end %> | |
<% end %> | |
CODE | |
file 'app/views/shared/_subnav.html.erb', <<-CODE | |
<% if session[:user_id] %> | |
<ul class='nav nav-tabs'> | |
<li><a href='#'>Welcome</a></li> | |
<li><a href='#'>Latest activity</a></li> | |
<li <% if controller_name == 'users' %> class='active' <% end %> >users</li> | |
</ul> | |
<% end %> | |
CODE | |
#add application methods | |
inject_into_file "app/controllers/application_controller.rb", :after => 'protect_from_forgery with: :exception' do | |
<<-EOS | |
before_action :authorize | |
protected | |
def authorize | |
unless User.find_by(id: session[:user_id]) | |
sessions_destroy_path | |
session[:last_seen] = Time.now | |
redirect_to login_url, notice: 'Please log in' | |
else | |
reset_session if session[:last_seen] < 10.minutes.ago | |
session[:last_seen] = Time.now | |
end | |
end | |
def verify_registration | |
@user = User.find_by(id: session[:user_id]) | |
if @user.tenant_id.nil? | |
flash[:warning] = 'you need to choose a plan' | |
redirect_to chooseaplan_url | |
else | |
flash[:notice] = "Hi #{@user.first_name}, your company is: #{@user.tenant.company}(#{@user.tenant_id}), and your role is: #{@user.role.name}, your plan is #{@user.tenant.plan.name} sessions : user_tenant_id : #{session[:user_tenant_id]}, user_id = #{session[:user_id]} last_seen #{session[:last_seen]}" | |
end | |
end | |
def authorize_write | |
@role = Role.find_by(id: session[:user_role_id]) | |
if @role.name == 'author' | |
flash[:danger] ='You do not have permission to (write edit or delete)' | |
redirect_to :back | |
end | |
end | |
def authorize_delete | |
@role = Role.find_by(id: session[:user_role_id]) | |
if @role.name == 'moderator' | |
flash[:danger] ='You do not have permission to (delete)' | |
redirect_to :back | |
end | |
end | |
def verify_max_users | |
@max_user = Tenant.find_by(id: session[:user_tenant_id]).plan.max_members | |
@count_users = User.where(tenant_id: session[:user_tenant_id]).count | |
if @max_user <= @count_users | |
flash[:danger] = "You can't add more than #{@max_user} users" | |
redirect_to :back | |
end | |
end | |
def authorize_admin_user | |
@role = Role.find_by(id: session[:user_role_id]) | |
unless @role.name == 'Admin' | |
flash[:danger] ='You do not have Admin permissions' | |
redirect_to :back | |
end | |
end | |
EOS | |
# seed file | |
inject_into_file "db/seeds.rb", :after => "" do | |
<<-EOS | |
Plan.delete_all | |
Plan.create([ | |
{name: 'Demo',period: '30',max_members: '2'}, | |
{name: 'eco',period: '90',max_members: '1000'}, | |
{name: 'silver',period: '180',max_members: '2000'}, | |
{name: 'gold',period: '360',max_members: '3000'}, | |
]) | |
Role.delete_all | |
Role.create([{name: 'Admin'},{name: 'moderator'},{name: 'author'},{name: 'Client'}]) | |
EOS | |
end | |
# session file | |
inject_into_file "app/controllers/sessions_controller.rb", :after => 'ApplicationController' do | |
<<-EOS | |
skip_before_action :authorize | |
EOS | |
end | |
inject_into_file "app/controllers/sessions_controller.rb", :after => 'def create' do | |
<<-EOS | |
user = User.find_by(email: params[:email]) | |
if user and user.authenticate(params[:password]) | |
session[:user_id] = user.id | |
session[:user_name] = user.first_name | |
session[:last_seen] = Time.now | |
unless user.tenant_id.nil? | |
session[:user_tenant_id] = user.tenant_id | |
else | |
session[:user_tenant_id] = nil | |
end | |
unless user.role_id.nil? | |
session[:user_role_id] = user.role_id | |
else | |
session[:user_role_id] = nil | |
end | |
redirect_to home_url | |
else | |
redirect_to login_url, alert: "Invalid email/Password combination" | |
end | |
EOS | |
end | |
inject_into_file "app/controllers/sessions_controller.rb", :after => 'def destroy' do | |
<<-EOS | |
session[:user_id] = nil | |
redirect_to pages_index_url, notice: "Logged out" | |
EOS | |
end | |
# page with choseplan | |
inject_into_file "app/controllers/pages_controller.rb", :after => 'ApplicationController' do | |
<<-EOS | |
skip_before_action :authorize, only: [:index, :about, :contact, :help] | |
before_action :verify_registration, only: [:home] | |
def chooseaplan | |
@plan = Plan.all | |
@tenant = Tenant.new | |
end | |
def createaplan | |
@tenant = Tenant.new | |
@tenant.company = params[:company] | |
@tenant.url = params[:company]+".site.com" | |
@tenant.plan_id = params[:Plan] | |
if @tenant.save | |
@last_tenant = Tenant.find_by(company: params[:company]) | |
@role = Role.find_by(name: 'Admin') | |
@user = User.find_by(id: session[:user_id]) | |
if @user.update_attributes :tenant_id => @last_tenant.id, :role_id => @role.id | |
session[:user_tenant_id] = @last_tenant.id | |
session[:user_role_id] = @role.id | |
redirect_to home_url | |
else | |
@user.errors.full_messages.each do |msg| | |
flash[:danger] = msg | |
end | |
redirect_to chooseaplan_url | |
end | |
else | |
@tenant.errors.full_messages.each do |msg| | |
flash[:danger] = msg | |
end | |
redirect_to chooseaplan_url | |
end | |
end | |
EOS | |
end | |
#injecting plans | |
inject_into_file "app/controllers/plans_controller.rb", :after => 'ApplicationController' do | |
<<-EOS | |
skip_before_action :authorize | |
EOS | |
end | |
#injecting roles | |
inject_into_file "app/controllers/roles_controller.rb", :after => 'ApplicationController' do | |
<<-EOS | |
skip_before_action :authorize | |
EOS | |
end | |
#injecting tenants | |
inject_into_file "app/controllers/tenants_controller.rb", :after => 'ApplicationController' do | |
<<-EOS | |
skip_before_action :authorize | |
EOS | |
end | |
#injecting users | |
inject_into_file "app/controllers/users_controller.rb", :after => 'ApplicationController' do | |
<<-EOS | |
skip_before_action :authorize, only: [:create, :new] | |
before_action :verify_max_users, only: [:addnewuser, :addnewusercreate] | |
before_action :authorize_admin_user, only: [:index, :addnewuser, :addnewusercreate, :destroy] | |
def addnewuser | |
@user = User.new | |
@roles = Role.all | |
end | |
def addnewusercreate | |
@user = User.new(user_params) | |
@user.tenant_id = session[:user_tenant_id] | |
respond_to do |format| | |
if @user.save | |
format.html { redirect_to users_url, notice: "User #{@user.first_name} was successfully created, Please Log in." } | |
format.json { render action: 'show', status: :created, location: @user } | |
else | |
@roles = Role.all | |
format.html { render action: 'addnewuser' } | |
format.json { render json: @user.errors, status: :unprocessable_entity } | |
end | |
end | |
end | |
EOS | |
end | |
#injecting users | |
inject_into_file "app/controllers/users_controller.rb", :after => 'def index' do | |
<<-EOS | |
@users = User.order(id: :desc).find_all_by_tenant_id(session[:user_tenant_id]) | |
@max_user = Tenant.find_by(id: session[:user_tenant_id]).plan.max_members | |
@count_users = User.find_all_by_tenant_id(session[:user_tenant_id]).count | |
EOS | |
end | |
#injecting users | |
inject_into_file "app/controllers/users_controller.rb", :after => 'if @user.update(user_params)' do | |
<<-EOS | |
session[:user_name] = @user.first_name | |
EOS | |
end | |
#injecting users | |
inject_into_file "app/controllers/users_controller.rb", :after => 'def destroy' do | |
<<-EOS | |
begin | |
@user.destroy | |
flash[:notice] = "User #{@user.first_name} deleted" | |
rescue StandardError => e | |
flash[:warning] = e.message | |
end | |
EOS | |
end | |
#injecting model users | |
inject_into_file "app/models/users.rb", :after => 'ActiveRecord::Base' do | |
<<-EOS | |
email_regex = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i | |
validates :email, presence: true, | |
:format => { :with => email_regex }, | |
uniqueness: true | |
validates :first_name, presence: true | |
validates :last_name, presence: true | |
belongs_to :tenant | |
belongs_to :role | |
EOS | |
end | |
#injecting model tenant | |
inject_into_file "app/models/tenant.rb", :after => 'ActiveRecord::Base' do | |
<<-EOS | |
belongs_to :plan | |
has_many :users | |
validates :company, presence: true, uniqueness: true | |
EOS | |
end | |
#injecting model role | |
inject_into_file "app/models/role.rb", :after => 'ActiveRecord::Base' do | |
<<-EOS | |
has_many :users | |
EOS | |
end | |
#injecting model plan | |
inject_into_file "app/models/plan.rb", :after => 'ActiveRecord::Base' do | |
<<-EOS | |
has_many :tenants | |
EOS | |
end | |
file 'app/views/pages/chooseaplan.html.erb', <<-CODE | |
<%= form_tag({:action => 'createaplan'}, {:class => "form-signin"} ) do %> | |
<% if @tenant.errors.any? %> | |
<div id="error_explanation"> | |
<h2><%= pluralize(@tenant.errors.count, "error") %> prohibited this tenant from being saved:</h2> | |
<ul> | |
<% @tenant.errors.full_messages.each do |msg| %> | |
<li><%= msg %></li> | |
<% end %> | |
</ul> | |
</div> | |
<% end %> | |
<h2 class="form-signin-heading">Choose your plan</h2> | |
<%= text_field_tag :company, params[:company], class: "form-control", placeholder: "Company name" %> | |
<%= select_tag "Plan", options_from_collection_for_select(@plan, "id", "name"), class: "form-control " %> | |
<%= submit_tag "Continue", class: "btn btn-lg btn-primary btn-block" %> | |
<% end %> | |
CODE | |
file 'app/views/pages/createaplan.html.erb', <<-CODE | |
CODE | |
inject_into_file "app/views/sessions/new.html.erb" do | |
<<-EOS | |
<%= form_tag({:action => 'create'}, {:class => "form-signin"} ) do %> | |
<h2 class="form-signin-heading">Please sign in</h2> | |
<%= text_field_tag :email, params[:email], class: "form-control", placeholder: "Email" %> | |
<%= password_field_tag :password, params[:password], class: "form-control", placeholder: "Password" %> | |
<label class="checkbox"> | |
<input value="remember-me" type="checkbox"> Remember me | |
</label> | |
<%= submit_tag "Sign-in", class: "btn btn-lg btn-primary btn-block" %> | |
if you havn't an account <%= link_to "Sign-up", new_user_url %> | |
<% end %> | |
EOS | |
end | |
file 'app/views/users/addnewuser.html.erb', <<-CODE | |
<div class="panel panel-primary"> | |
<div class="panel-heading"> | |
<h3 class="panel-title">Invite a new user to your floral_wind account</h3> | |
</div> | |
<div class="panel-body"> | |
<p>The person you invite will receive an email with an invitation link. When they click the link they can change their own password. Then they will be part of your account!</p> | |
<%= form_for @user, url: addnewusercreate_url ,:html => {:class => "form-signin"} do |f| %> | |
<% if @user.errors.any? %> | |
<div id="error_explanation"> | |
<h2><%= pluralize(@user.errors.count, "error") %> prohibited this user from being saved:</h2> | |
<ul> | |
<% @user.errors.full_messages.each do |msg| %> | |
<li><%= msg %></li> | |
<% end %> | |
</ul> | |
</div> | |
<% end %> | |
<h4 class="form-signin-heading">Enter contact info for the person you want to invite</h4> | |
<%= f.label :first_name %> | |
<%= f.text_field :first_name, class: "form-control", placeholder: "first_Name" %> | |
<%= f.label :last_name %> | |
<%= f.text_field :last_name, class: "form-control", placeholder: "last_Name" %> | |
<%= f.label :email %> | |
<%= f.text_field :email, class: "form-control", placeholder: "Email" %> | |
<%= f.label :role_id %> | |
<%= f.select :role_id, options_from_collection_for_select(@roles, "id", "name",@user.role_id),{ include_blank: false }, {class: "form-control"} %> | |
<%= f.label :password %> | |
<%= f.password_field :password, class: "form-control", placeholder: "Password" %> | |
<%= f.label :password_confirmation %> | |
<%= f.password_field :password_confirmation, class: "form-control", placeholder: "Re-type Password" %> | |
<%= f.submit "Add user", class: "btn btn-lg btn-primary btn-block" %> | |
<% end %> | |
</div> | |
</div> | |
CODE | |
inject_into_file "app/views/users/index.html.erb", :after => "" do | |
<<-EOS | |
<div class="panel panel-default"> | |
<div class="panel-body"> | |
You can create a maximum of users of <strong><%= @max_user %></strong> <br> | |
you have <strong><%= @count_users %></strong> users | |
</div> | |
</div> | |
<%= link_to 'Add new user', addnewuser_path, :class => "btn btn-default" %> | |
<% @users.each do |user| %> | |
<div class="media"> | |
<a class="pull-left" href="#"> | |
<%= image_tag('64x64.png', class: "media-object") %> | |
</a> | |
<div class="media-body"> | |
<h4 class="media-heading"> | |
<%= link_to user.first_name , user %> <span class="label label-default"><%= user.role.name %></span></h4> | |
<%= user.email %> | |
<p class="pull-right" id="tools-user"> | |
created at <%= user.created_at %> <%= link_to 'Edit', edit_user_path(user) %> | <%= link_to 'Destroy', user, method: :delete, data: { confirm: 'Are you sure? All the notes, emails, tasks and user information associated with this user will be erased' } %></p> | |
</div> | |
</div> | |
<% end %> | |
<% content_for :right do %> | |
<p>What can an "Admin" do?</p> | |
<p>Admins have access to delete other users' notes, change account settings, and various other administrative tasks. You should only give admin access to people you trust with the responsibility.</p> | |
<p>Reset password</p> | |
<p>Each person's password is private to them, but you can email instructions to choose a new password.</p> | |
<p>Re-send invitation</p> | |
<p>You can re-send the welcome invitation email if it went to the wrong email address or if it wasn't received. | |
</p> | |
<% end %> | |
EOS | |
end | |
#injecting twitter bootstrap links to js | |
inject_into_file "app/assets/javascripts/application.js", :after => 'ApplicationController' do | |
<<-EOS | |
//= require twitter/bootstrap | |
//= require jquery.ui.all | |
EOS | |
end | |
#injecting twitter bootstrap links to css | |
inject_into_file "app/assets/stylesheets/application.css", :after => '*= require_tree .' do | |
<<-EOS | |
*= require twitter/bootstrap | |
*= require jquery.ui.all | |
EOS | |
end | |
# setup git and initial commit | |
git :init | |
git :add => "." | |
git :commit => "-a -m 'initial commit'" | |
say <<-EOS | |
============================================================================ | |
Your app is now available. | |
EOS |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment