Listing users
Name |
---|
New User
14.2 Iteration I2: Authenticating Users 13.3 Playtime
Scaffold the user model
rails generate scaffold User name:string password_digest:string
[deprecated] I18n.enforce_available_locales will default to true in the future. If you really want to skip validation of your locale you can set I18n.enforce_available_locales = false to avoid this message.
invoke active_record
create db/migrate/20140204194402_create_users.rb
create app/models/user.rb
invoke test_unit
create test/unit/user_test.rb
create test/fixtures/users.yml
route resources :users
invoke scaffold_controller
create app/controllers/users_controller.rb
invoke erb
create app/views/users
create app/views/users/index.html.erb
create app/views/users/edit.html.erb
create app/views/users/show.html.erb
create app/views/users/new.html.erb
create app/views/users/_form.html.erb
invoke test_unit
create test/functional/users_controller_test.rb
invoke helper
create app/helpers/users_helper.rb
invoke test_unit
create test/unit/helpers/users_helper_test.rb
invoke assets
invoke coffee
create app/assets/javascripts/users.js.coffee
invoke scss
create app/assets/stylesheets/users.css.scss
invoke scss
identical app/assets/stylesheets/scaffolds.css.scss
uncomment out bcrypt-ruby
edit Gemfile
# To use ActiveModel has_secure_password
gem 'bcrypt-ruby', '~> 3.0.0'
Run the migration
rake db:migrate
mv 20140204194402_create_users.rb 20140204000009_create_users.rb
[deprecated] I18n.enforce_available_locales will default to true in the future. If you really want to skip validation of your locale you can set I18n.enforce_available_locales = false to avoid this message.
== CreateUsers: migrating ====================================================
-- create_table(:users)
-> 0.0009s
== CreateUsers: migrated (0.0009s) ===========================================
Add validation, has_secure_password
edit app/models/user.rb
class User < ActiveRecord::Base
attr_accessible :name, :password, :password_confirmation
validates :name, :presence => true, :uniqueness => true
has_secure_password
end
Avoid redirect after create, update operations
edit app/controllers/users_controller.rb
def create
@user = User.new(params[:user])
respond_to do |format|
if @user.save
format.html { redirect_to users_url,
:notice => "User #{@user.name} was successfully created." }
format.json { render :json => @user,
:status => :created, :location => @user }
else
format.html { render :action => "new" }
format.json { render :json => @user.errors,
:status => :unprocessable_entity }
end
end
end
edit app/controllers/users_controller.rb
def update
@user = User.find(params[:id])
respond_to do |format|
if @user.update_attributes(params[:user])
format.html { redirect_to users_url,
:notice => "User #{@user.name} was successfully updated." }
format.json { head :ok }
else
format.html { render :action => "edit" }
format.json { render :json => @user.errors,
:status => :unprocessable_entity }
end
end
end
Display users sorted by name
edit app/controllers/users_controller.rb
def index
@users = User.order(:name)
respond_to do |format|
format.html # index.html.erb
format.json { render :json => @users }
end
end
Add Notice
edit app/views/users/index.html.erb
<h1>Listing users</h1>
<% if notice %>
<p id="notice"><%= notice %></p>
<% end %>
<table>
<tr>
<th>Name</th>
<th></th>
<th></th>
<th></th>
</tr>
<% @users.each do |user| %>
<tr>
<td><%= user.name %></td>
<td><%= link_to 'Show', user %></td>
<td><%= link_to 'Edit', edit_user_path(user) %></td>
<td><%= link_to 'Destroy', user, :confirm => 'Are you sure?', :method => :delete %></td>
</tr>
<% end %>
</table>
<br />
<%= link_to 'New User', new_user_path %>
Update form used to both create and update users
edit app/views/users/_form.html.erb
<div class="depot_form">
<%= form_for @user 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 %>
<fieldset>
<legend>Enter User Details</legend>
<div class="field">
<%= f.label :name, 'Name:' %>
<%= f.text_field :name, :size => 40 %>
</div>
<div class="field">
<%= f.label :password, 'Password:' %>
<%= f.password_field :password, :size => 40 %>
</div>
<div class="field">
<%= f.label :password_confirmation, 'Confirm:' %>
<%= f.password_field :password_confirmation, :size => 40 %>
</div>
<div class="actions">
<%= f.submit %>
</div>
</fieldset>
<% end %>
</div>
Demonstrate creating a new user
get /users
get /users/new
post /users
get http://localhost:3000/users
Show how this is stored in the database
sqlite3> select * from users
id = 1
name = dave
password_digest = $2a$10$CoElY/nG6GkrZNe/cvn2r.LmlbfLYf3FSxTWx1gxuL90WaGVz3VFq
created_at = 2014-02-04 19:44:15.616470
updated_at = 2014-02-04 19:44:15.616470
Update tests to reflect the changes in redirection and uniqueness
edit test/functional/users_controller_test.rb
require 'test_helper'
class UsersControllerTest < ActionController::TestCase
setup do
@input_attributes = {
:name => "sam",
:password => "private",
:password_confirmation => "private"
}
@user = users(:one)
end
#...
test "should create user" do
assert_difference('User.count') do
post :create, :user => @input_attributes
end
assert_redirected_to users_path
end
#...
test "should update user" do
put :update, :id => @user.to_param, :user => @input_attributes
assert_redirected_to users_path
end
end
Make sure that all test names are unique
edit test/fixtures/users.yml
# Read about fixtures at
# http://api.rubyonrails.org/classes/ActiveRecord/Fixtures.html
one:
name: dave
password_digest: <%= BCrypt::Password.create('secret') %>
two:
name: susannah
password_digest: MyString
rake test
[deprecated] I18n.enforce_available_locales will default to true in the future. If you really want to skip validation of your locale you can set I18n.enforce_available_locales = false to avoid this message.
[deprecated] I18n.enforce_available_locales will default to true in the future. If you really want to skip validation of your locale you can set I18n.enforce_available_locales = false to avoid this message.
Loaded suite /home/rubys/.rvm/gems/ruby-1.8.7-p374/gems/rake-10.1.1/lib/rake/rake_test_loader
Started
.......
Finished in 0.296423 seconds.
7 tests, 28 assertions, 0 failures, 0 errors
[deprecated] I18n.enforce_available_locales will default to true in the future. If you really want to skip validation of your locale you can set I18n.enforce_available_locales = false to avoid this message.
Loaded suite /home/rubys/.rvm/gems/ruby-1.8.7-p374/gems/rake-10.1.1/lib/rake/rake_test_loader
Started
..........................................
Finished in 1.161934 seconds.
42 tests, 72 assertions, 0 failures, 0 errors
[deprecated] I18n.enforce_available_locales will default to true in the future. If you really want to skip validation of your locale you can set I18n.enforce_available_locales = false to avoid this message.
Loaded suite /home/rubys/.rvm/gems/ruby-1.8.7-p374/gems/rake-10.1.1/lib/rake/rake_test_loader
Started
...
Finished in 0.857555 seconds.
3 tests, 75 assertions, 0 failures, 0 errors