10.4 destroying users.
in this chapter, we will add destroy action to users controller to finish REST.
?
first, we need to add administrative users who can use the destroy action. so we need to add a new attr of admin which is a boolean.
?
and in the model, you can use admin? to get this attr value.
?
1. let's write the unit test first.:
?
?
describe "admin attribute" do before(:each) do @user = User.create!(@attr) end it "should respond to admin" do @user.should respond_to(:admin) end it "should not be an admin by default" do @user.should_not be_admin end it "should be convertible to an admin" do @user.toggle!(:admin) @user.should be_admin end endend?
note, we use?
?
@user.toggle!(:admin)
?
rails can detect the boolean attr, and auto add a new question mark method of admin?
?
2. next, let's add a new attr to users table.
?
?
rails g migration add_admin_to_users admin:boolean
?this wiil add a new column, and the default value is nil.
?
so to be clear, you can change the migration file:
?
?
add_column :users, :admin, :boolean, :default => false
?
3. next, we need to migrate to database, and also do test:prepare to update test database.
?
?
rake db:migraterake db:test:prepare
?
4. revisiting attr_accessible
you may wondering, why we use toggle!, instead of assign ":admin=>true" directly?
because this will not work, as we defined attr_accessible, and :admin is not in the list.
so you can't do mass assignment for admin column.
?
explicily define attr_accessible is crucial for a good site security. if you omit it, any user can issue such request:
?
put /users/17?admin=1
?then this user can do everything bad.
?
so define attr_accessible for every model is a good practice.
?
5. adding destroy action:
?
first, let's add delete link to the user's list page:
?
<li> <%= gravatar_for user, :size => 30 %> <%= link_to user.name, user %> <% if current_user.admin? %> | <%= link_to "delete", user, :method => :delete, :confirm => "You sure?", :title => "Delete #{user.name}" %> <% end %></li>?note:
the method is ":delete", so this link will issue a DELETE request.
Web browsers can't send DELETE link natively, so rails fakes with javascript.
But to get this delete link to work, we have to include rails default javascript library, :defaults.
?
<%= javascript_include_tag :defaults %>
?this line code is in app/views/layouts/application.html.erb
def destroy User.find_by_id(params[:id]).destroy flash[:success] = "User destroied." redirect_to users_path end
?note:
User.find_by_id(params[:id]).destroythis is how to destroy a record from the database.