Rails 求助:rails 3.26 生成 model 自动生成 attr_accessible 的问题

hanhor · July 06, 2012 · Last by zhou replied at March 25, 2013 · 4547 hits

RT,学习@Terry老师在http://railscasts-china.com 的视频教程时,我电脑使用的 rails 版本: rails -v:Rails 3.2.6,每次生产一个 model 时。都会在 model 中自动加上 attr_accessible,现在用 omniauth 时,出现了这个问题,代码是这样的,

class User < ActiveRecord::Base
  attr_accessible :email, :nickname
  validates :nickname, :presence => true
  validates :email, :presence => true, :uniqueness => true
  has_many :authentications
  has_many :posts

  accepts_nested_attributes_for :authentications

  def add_auth(auth)
    authentications.create(:provider => auth[:provider],
      :uid => auth[:uid])
  end

  class << self
    def from_auth(auth)
      locate_auth(auth) || locate_email(auth) || create_auth(auth)
    end

    def locate_auth(auth)
      Authentication.find_by_provider_and_uid(auth[:provider],
                                              auth[:uid]).try(:user)
    end

    def locate_email(auth)
      user = find_by_email(auth[:info][:email])
      return unless user
      user.add_auth(auth)
      user
    end

    def create_auth(auth)
      create!(
        :nickname => auth[:info][:nickname],
        :email => auth[:info][:email],
        :authentications_attributes => [
          Authentication.new(:provider => auth[:provider],
                             :uid => auth[:uid]
                            ).attributes
      ])

    end
  end
end

代码是视频教程中@Terry老师的,我自己手动打出来的。第二行attr_accessible :email, :nickname是生成这个 model 时自己生成的. 现在我访问http://127.0.0.1:3000/auth/github/ 或者http://127.0.0.1:3000/auth/identity/register 时,都会报这个错误:

ActiveModel::MassAssignmentSecurity::Error in SessionsController#create

Can't mass-assign protected attributes: authentications_attributes

其中 SessionsController 中的代码是这样的:

class SessionsController < ApplicationController
  def create
    user = User.from_auth(request.env['omniauth.auth'])
    session[:user_id] = user.id
    flash[:notice] = "Welcome #{user.nickname}"
    redirect_to posts_path
  end

  def new
    flash[:failure_provider] = request.env['omniauth.error.strategy'].name
    flash[:failure_type] = request.env['omniauth.error.type']
  end
end

. 自己尝试这样解决: 将authentications_attributes也加在user_model 的 attr_accessible :email, :nickname中,即 attr_accessible :email, :nickname, :authentications_attributes,这时,又报错

ActiveModel::MassAssignmentSecurity::Error in SessionsController#create

Can't mass-assign protected attributes: created_at, updated_at

发到这里,恳请各位帮忙下。谢谢~

再加上 created_at, updated_at

不过有点奇怪这个 gem 为什么要改 created_at 和 updated_at。

@Rei white list 一定要打开吗?

#2 楼 @fresh_fish 建议打开,开发的时候麻烦点也好过上线之后暴漏洞。

4.0 参数白名单有可能移到 contorller。

@Rei 我加上了还是有问题,这会电脑网络坏了,等会把错误贴上来

#3 楼 @Rei 我把created_at, updated_at加进去还是提示

ActiveModel::MassAssignmentSecurity::Error in SessionsController#create

Can't mass-assign protected attributes: created_at, updated_at

我把 attr_accessible :email, :nickname 依然有如上的错误

#5 楼 @HanHor attr_accessible :email, :nickname, :authentications_attributes ,:created_at,:updated_at 这样也不行?

#6 楼 @jjym 嗯,是的,我也加进去了..

可能是 authentications 的 Model 里面也有 attr_accessible

#8 楼 @Rei 嗯,确实是的,我把两边都注释掉或者两边都加上:created_at,:updated_at 就可以了。

那这样的话数据库中这些字段在这边加入 attr_accessible 里面没必要啊

@poshboytl 这个问题在视频处备注一下,会不会比较好呢?

奇怪啊.. 我从代码里面没看到 对 created_at 和 updated_at 做了 mass-assign。你虽然这样解决了这个问题。但是最好还是找到原因。加 created_at 和 updated_at 其实是不太合理的...

#11 楼 @poshboytl 这个我也觉得奇怪,但是我也出现了一样的问题。

@poshboytl

Authentication.new(:provider => auth[:provider],
                             :uid => auth[:uid]).attributes

原来是这个会返回所以的 attributes 的值,其中包括有 created_at 和 updated_at。改一改可以解决这个问题:

def create_auth(auth)
  user = create!(
      :nickname => auth[:info][:nickname],
      :email => auth[:info][:email])
  user.authentications.build(:provider => auth[:provider],
                             :uid => auth[:uid])
end

我也遇到过类似问题,解决的办法是 user.rb 中加入 attr_protected :authentications,你试试看能不能解决

You need to Sign in before reply, if you don't have an account, please Sign up first.