Я читал на проблемах безопасности направляющих и той, которая делает меня, самым соответствующим является массовое присвоение. Мое приложение использует attr_accessible, однако я не уверен, знаю ли я вполне, какой лучший способ обработать выставленные отношения. Давайте предположим, что у нас есть основной веб-сайт создания/владения содержания. Пользователь может иметь, создают сообщения в блоге и связали одну категорию с тем сообщением в блоге.
Таким образом, у меня есть три модели:
Я позволяю массовое присвоение на category_id, таким образом, пользователь мог ноль это, изменить его на одну из их категорий, или через массовое присвоение, я предполагаю, что они могли изменить его на чужую категорию. Это - то, где я довольно не уверен в том, какой лучший способ продолжиться был бы.
Ресурсы, которые я исследовал (особенно railscast № 178 и ресурс, который был обеспечен от этого railscast), оба упоминания, что ассоциация не должна быть массово-присваиваемой, который имеет смысл. Я просто не уверен, как еще позволить пользователю изменять то, чем категория сообщения была бы railsy способом.
Какие-либо идеи о том, как лучше всего решить это? Я смотрю на него неправильный путь?
ОБНОВЛЕНИЕ: Надо надеяться, разъясняя мое беспокойство немного больше.
Скажем, я нахожусь в Сообщении, сделайте мне нужно что-то как следующее:
def create
@post = Post.new(params[:category])
@post.user_id = current_user.id
# CHECK HERE IF REQUESTED CATEGORY_ID IS OWNED BY USER
# continue on as normal here
end
Это походит на большую работу? Я должен был бы проверить это на каждом контроллере и в обновлении и в действии по созданию. Следует иметь в виду, что существуют больше, чем всего belongs_to отношение.
Хорошо, немного поискал, и, наконец, придумал что-нибудь для меня работоспособное. Мне нравится держать логику подальше от контроллеров, где это возможно, так что это решение основано на модели:
# Post.rb
validates_each :asset_category_id do |record, attr, value|
self.validates_associated_permission(record, attr, value)
end
# This can obviously be put in a base class/utility class of some sort.
def self.validates_associated_permission(record, attr, value)
return if value.blank?
class_string = attr.to_s.gsub(/_id$/, '')
klass = class_string.camelize.constantize
# Check here that the associated record is the users
# I'm leaving this part as pseudo code as everyone's auth code is
# unique.
if klass.find_by_id(value).can_write(current_user)
record.errors.add attr, 'cannot be found.'
end
end
Я также обнаружил, что рельсы 3.0 будут иметь лучший способ указать это вместо 3 строк, необходимых для ультра-общего validates_each.
http://ryandaigle.com/articles/2009/8/11/what-s-new-in-edge-rails-independent-model-validators
Ваш пользователь может изменить его через форму редактирования своего рода, я предполагаю.
На основании этого массовое назначение действительно для неманных типов, которые стремятся связываться с вашим приложением через такие вещи, как Curl. Я называю их кудрявыми детками.
Все, что сказать, если вы используете attr_protected
- (здесь вы помещаете поля, которые вы не хотите, чтобы они менялись) или любимый ребенок attr_accessible
(поля, которые в порядке изменить).
Вы услышите аргументы для обоих, но если вы используете attr_protected: user_id
в вашей модели, а затем в вашем категории CController # Создать действие Вы можете сделать что-то вроде
def create
@category = Category.new(params[:category])
@category.user_id = current_user.id
respond_to do |format|
....#continue on as normal here
end