在我的迁移中修改记录会引发authlogic错误

时间:2010-04-26 23:47:04

标签: ruby-on-rails migration authlogic

我在我的一个数据库表中添加了一些列,然后填充这些列:

def self.up
  add_column :contacts, :business_id, :integer
  add_column :contacts, :business_type, :string

  Contact.reset_column_information
  Contact.all.each do |contact|
    contact.update_attributes(:business_id => contact.client_id, :business_type => 'Client')
  end

  remove_column :contacts, :client_id
end

contact.update_attributes导致以下Authlogic错误:

You must activate the Authlogic::Session::Base.controller with a controller object before creating objects

我不知道这里发生了什么 - 我没有使用控制器方法来修改表中的每一行。我也不是在创造新物品。

如果联系人表为空,则 错误。

我有一个谷歌,当你运行你的控制器测试时似乎会发生这个错误,并且通过向他们添加before_filter :activate_authlogic来修复,但这在我的情况下似乎并不相关。

有什么想法吗?我很难过。

这是我要求的联系人模型:

class Contact < ActiveRecord::Base
  belongs_to :contactable, :polymorphic => true
  has_many :phone_numbers, :as => :callable
  has_many :email_addresses, :as => :emailable

  accepts_nested_attributes_for :phone_numbers
  accepts_nested_attributes_for :email_addresses

  validates_presence_of :first_name, :last_name
  validates_format_of :first_name, :last_name, :with => /^[-a-zA-Z ]+$/

  default_scope :order => 'first_name ASC, last_name ASC'

  def full_name
    "#{self.first_name} #{self.last_name}"
  end

  def to_s
    full_name
  end
end

版本信息: Rails 2.3.5,Authlogic 2.1.3

rake db:migrate --trace output 可以在这里找到:http://pastie.org/944446

观察员信息:

我有ActivityObserver观察我的Contact模型并使用Activity回调创建after_update

在我的Activity模型中,我 hackishly @current user与使用before_save回调创建的活动相关联。

以下是代码的相关摘要:

class ActivityObserver < ActiveRecord::Observer
  observe :contact

  def after_update(subject)
    Activity.create(:action => 'Updated', :subject => subject)
  end
end

class Activity < ActiveRecord::Base
  belongs_to :subject, :polymorphic => true
  belongs_to :user

  def before_save
    # FIXME: This is a messy hack way to get the user's id
    self.user = UserSession.find.record
  end
end

这是绝对 Authlogic参与的地方。 KandadaBoggu是winrar - 非常感谢您的见解!!!

就修复而言,我认为从根本上说没有任何修正。如果我想通过迁移更新我的联系人时创建活动,根据定义,没有@current_user要关联。我会想办法解决这个问题,但KandadaBoggu肯定回答了我的问题。

6 个答案:

答案 0 :(得分:3)

在更新Contact模型时,如何创建Authlogic会话对象。在Contact模型的过滤器之前/之后是否有任何观察者?

来自Authlogic::Session::Base.activated?

的authlogic文档
# Returns true if a controller has been set and can be used properly. 
# This MUST be set before anything can be done. Similar to how ActiveRecord 
# won't allow you to do anything without establishing a DB connection. In your 
# framework environment this is done for you, but if you are using Authlogic 
# outside of your framework, you need to assign a controller object to Authlogic 
# via Authlogic::Session::Base.controller = obj. See the controller= method for 
# more information.

通过在修改controller模型实例之前设置Contact来解决此问题的一种方法,即:

def self.up
  add_column :contacts, :business_id, :integer
  add_column :contacts, :business_type, :string

  Authlogic::Session::Base.controller = 
                       Authlogic::ControllerAdapters::RailsAdapter.new(self)

  Contact.reset_column_information
  Contact.all.each do |contact|
    contact.update_attributes(:business_id => contact.client_id, 
              :business_type => 'Client')
  end

  remove_column :contacts, :client_id
end

注意:我还没有测试过这段代码。

答案 1 :(得分:1)

我不确定这是否有用,但值得一试:

替换此行:

contact.update_attributes(:business_id => contact.client_id, :business_type => 'Client')

使用:

contact.update_attribute(:business_id, contact.client_id)
contact.update_attribute(:business_type, 'Client')

我无法重现你的问题,所以我只是在这里猜测:

无论出于何种原因,update_attributes都会触发此异常。 我猜它是在验证阶段。因此,我们使用update_attribute跳过验证。

如果仍然无效,则会在堆栈的下方触发异常。 最糟糕的情况是,您可以编写一些SQL来更新模型。

答案 2 :(得分:0)

这很奇怪。我根本没有看到如何在迁移中调用Authlogic。

你试过rake db:migrate --trace吗?

一想法 - 你可以试试:

contact.business_id = contact.client_id
contact.business_type = 'Client'
contact.save_without_session_maintenance

答案 3 :(得分:0)

正如我所知道的

 update_attributes(attributes) 

只接受一个参数。 你可能意味着

 update_attribute(name,value)

答案 4 :(得分:0)

注意:我假设您的应用中有一个名为User的模型。如果没有,无论哪个人使用acts_as_authentic就是我的意思。

简短版本: 将以下内容添加到迁移中:

User.controller = true

UserSession.controller = true

如果修复它,那么问题是您的迁移正在尝试加载您的用户模型,这需要设置一个控制器来运行。

如果我所描述的内容不起作用,那么浏览http://github.com/binarylogic/authlogic/blob/v2.1.3/lib/authlogic/session/activation.rb来源可能是您想要开始的地方。

编辑:

添加到迁移的开始:

module Authlogic::ActsAsAuthentic::Base::Config
  def acts_as_authentic(unsupported_options = nil, &block)
  end
end

这应该禁用acts_as_authentic方法,这样你的模型就不会引入所有额外的东西。

答案 5 :(得分:-1)

这应该如下所示,不要检查。

belongs_to :contactable, :polymorphic => true, :foreign_key=>'client_id'