0

我有一个简单的嵌套表单,我正在设置一个带有隐藏字段的嵌套属性:

<%= role_form.hidden_field :company_id, :value => session[:company_id] %>

这里的想法是我通过当前会话变量Company的集合将此嵌套模型(基于角色的权限系统)关联到另一个模型。company_id我的问题是用户可以发送请求并随意创建/更新角色company_id并获得对另一家公司帐户的访问权限。

我可以强制嵌套模型属性为此会话值或验证吗?

我在考虑创建:

@user = User.new(params[:user])
@user.roles.first.company_id = session[:company_id]

对于更新,我可以做同样的事情。

至于我尝试的验证:

accepts_nested_attributes_for :roles, :limit => 1, :allow_destroy => true , :reject_if => proc { |attributes| attributes['company_id'] != session[:company_id] }

但看起来您无法访问模型中的会话信息。

任何人都知道我是否可以通过这两种方式做到这一点?

4

1 回答 1

1

与其将 company_id 存储在 session 中,不如向 company 添加一个随机生成的 token 列,并通过 Company.find_by_token(session[:token]) 获取 id。如果您查看此 Railscast on authentication中的 current_user 方法,它的想法是相同的。

编辑:对不起,我误解了你的问题。您的视图中根本不应该有隐藏的 company_id 字段。您应该在创建方法中手动设置它:

@user = User.new(params[:user])
@user.company_id = session[:company_id]

您可以通过保护 company_id 免受模型中的大规模分配来保护 company_id 免受用户更改输入名称的影响:

attr_protected :company_id

有关更多信息,请参阅有关批量分配保护的导轨指南。注意:更常见的解决方案是这样的:

class ApplicationController < ActionController::Base

  protect_from_forgery

  def current_company
    @current_company ||= Company.find_by_auth_token!(cookies[:auth_token]) if cookies[:auth_token]
  end
end

class User < ApplicationController
  def create
    @user = current_company.users.build(params[:user])
  end
end

更新 2:

因此,您正在创建一个用户和一个角色,并希望对它们进行单独的验证,这应该可以满足您的需求。

role_params = params[:user].delete :role # Change to the appropriate symbol for your form
@user = User.new(params[:user])
role = @user.roles.build(role_params)
role.company_id = session[:company_id]

if(@user.save and role.user_id = @user.id and role.save) # Might want to just check for valid instead of trying to save
...
于 2012-08-11T23:38:15.453 回答