2

У меня есть поле в моей модели User, которое защищено, потому что оно определяет уровень зазора. Поэтому его следует оставить защищенным, а не массовым назначением. Так что даже если атрибуты по умолчанию защищены в 3.2, это на самом деле поведение, которое я хочу.Назначение защищенного атрибута в Rails

Однако, по одному методу контроллера, я хочу разрешить менеджеру назначать это поле, например, при создании пользователя или обновлении пользователя.

Как разрешить присвоение этого атрибута определенным действиям контроллера?

К примеру, у меня есть контроллер:

# app/controllers/admin/users_controller.rb 

def create 
    @user = User.new(params[:user]) 
# ... 
end 

Теперь то, что я хотел бы сделать, это исключить clearance из params[:user], но, кажется, отфильтрованы и поднимать и исключение даже до того, что линия будет достигнута (I попробовал поставить debugger прямо перед этой линией и даже прокомментировать это, он все же вызвал исключение).

Где защищенные атрибуты попадают, если не при вызове User#new?

+0

Защищенные атрибуты должны быть уловлены перед вызовом 'User # new', за исключением случаев, когда, как и в моем случае, gem Cancan загружает ресурс. –

ответ

4

The Rails way, чтобы сделать это было бы присваивать атрибуты без защиты или использовать роль администратора:

@user = User.new 
@user.assign_attributes(params[:user], :without_protection => true) 
@user.save 

Однако, я нашел, что это немного утомительно, так что я написал драгоценный камень под названием sudo_attributes, что дает (на мой взгляд) лучше API:

@user = User.sudo_new(params[:user]) 
@user.save 

Он имитирует все Rails экземпляра, создание и методы обновления (новые, строить, создавать, создавать !, update_attributes и т.д.).

0

В прошлом я благоприятствование давая такую ​​операцию своего собственного метода содержал, что только устанавливает это значение:

# app/controllers/admin/users_controller.rb 

def full_clearance 
    User.find(params[:id]).update_attribute(:clearance, 'full') 
end 

def restricted_clearance 
    User.find(params[:id]).update_attribute(:clearance, 'restricted') 
end 

Теперь, глядя на the Rails way Beerlington упоминался, я предпочел бы использовать роли, чтобы дать что частности доступ действия к атрибуту клиренса:

# /app/models/user.rb 

attr_accessible :attributes_accessible_by_default, ..., :clearance, :as => :manager 

# app/controllers/admin/users_controller.rb 

def create 
    @user = User.new(params[:user].merge(:as => :manager) 
# ... 
end 

в этом случае возможно даже, чтобы дать доступ на основе атрибута роли на пользователя:

# app/controllers/admin/users_controller.rb 

def create 
    @user = User.new(params[:user].merge(:as => current_user.role.to_sym) 
# ... 
end 

, но это может привести к возникновению ошибок.