Я построил связь «многие ко многим» между пользователями и ролями.
Когда пользователь не входит в систему, я скрыл функцию редактирования роли, используя
используя следующий код:
просмотр / пользователи / edit.html.erb
<%= error_messages_for :user %>
<% form_for @user do |f| -%>
<p><label for="login">Login</label><br/>
<%= f.text_field :login %></p>
<p><label for="email">Email</label><br/>
<%= f.text_field :email %></p>
<p><label for="password">Password</label><br/>
<%= f.password_field :password %></p>
<p><label for="password_confirmation">Confirm Password</label><br/>
<%= f.password_field :password_confirmation %></p>
<% if admin? %>
<% for role in Role.find(:all) %>
<div>
<%= check_box_tag "user[role_ids][]", role.id, @user.roles.include?(role) %>
<%= role.name %>
</div>
<% end %>
<% else %>
<% hidden_field :email, :email %>
<% end %>
<p><%= submit_tag 'Update' %></p>
<% end %>
вывод терминала, был тем, что я ожидал и выглядит следующим образом:
Processing UsersController#update (for 127.0.0.1 at 2010-01-05 21:28:54) [PUT]
Parameters: {"commit"=>"Update", "action"=>"update", "_method"=>"put", "authenticity_token"=>"E6qUNM3gS9OmxuAZpmF7FE2Mr/lowznNLMd6ENNT6uk=", "id"=>"5", "controller"=>"users", "user"=>{"password_confirmation"=>"[FILTERED]", "password"=>"[FILTERED]", "login"=>"lesa", "email"=>"lesa@gmail.com"}}
Однако, когда я был удивлен, пользователь потерял свои права (до того, как ее пароль обновил ее роли: [1,2])
>> user = User.find_by_login("lesa")
=> #<User id: 5, login: "lesa", email: "lesa@gmail.com", crypted_password: "58026ae120d0686196df3c72c9e3df5da596326d", salt: "f02ef9e00d16f1b9f82dfcc488fdf96bf5aab4a8", created_at: "2009-12-29 15:15:51", updated_at: "2010-01-05 21:28:54", remember_token: nil, remember_token_expires_at: nil>
>> user.role_ids
=> []
>>
В контроллере пользовательской модели я использую:
attr_accessible :login, :email, :password, :password_confirmation, :role_ids
Каким образом пользователи без соответствующих прав (роли) НЕ могут обновлять свои role_ids? Очевидно, что у меня есть серьезные недостатки. Ниже приведен конечный вывод администратора, исправляющего права (роль) Лесы.
Processing UsersController#update (for 127.0.0.1 at 2010-01-05 21:34:01) [PUT]
Parameters: {"commit"=>"Update", "action"=>"update", "_method"=>"put", "authenticity_token"=>"/yC1s9T8yWZH+eM5fnhPwdeHPCTcT1d8IGoIn+tEd4Q=", "id"=>"5", "controller"=>"users", "user"=>{"password_confirmation"=>"[FILTERED]", "role_ids"=>["2"], "password"=>"[FILTERED]", "login"=>"lesa", "email"=>"lesa@gmail.com"}}
Код контроллера пользователя:
class UsersController < ApplicationController
# Be sure to include AuthenticationSystem in Application Controller instead
#routine that is excecuted before every action in controller "Before_filter
before_filter :login_required
require_role "admin", :for => [:index, :create, :destroy]
def index
@users = User.find(:all)
end
def show
@user = User.find(params[:id])
end
def destroy
@user = User.find(params[:id])
@user.destroy
redirect_to(users_url)
end
def edit
@user = User.find(params[:id])
end
def update
@user = User.find(params[:id])
params[:user][:role_ids] ||= []
if @user.update_attributes(params[:user])
flash[:notice] = 'User was successfully updated.'
redirect_to(user_path(@user))
else
render :action => 'edit'
end
end
# render new.rhtml
def new
end
def create
cookies.delete :auth_token
# protects against session fixation attacks, wreaks havoc with
# request forgery protection.
# uncomment at your own risk
# reset_session
@user = User.new(params[:user])
@user.save
if @user.errors.empty?
self.current_user = @user
redirect_back_or_default('/')
flash[:notice] = "Thanks for signing up!"
else
render :action => 'new'
end
end
end