代码之家  ›  专栏  ›  技术社区  ›  nfm

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

  •  2
  • nfm  · 技术社区  · 14 年前

    我正在向数据库表中添加一些列,然后填充这些列:

    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

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

    误差 在联系人表为空时发生。

    我有一个google,当您运行控制器测试时,似乎会发生此错误,并通过添加 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—跟踪输出 可在Paste在线找到: http://pastie.org/944446

    观察员信息:

    我有一个 ActivityObserver 那是在观察我的 Contact 建模并创建 Activity 使用 after_update 回调。

    在我的 活动 我是模型 卑鄙地 联想 @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参与其中。Kandaboggu是Winrar-非常感谢您的洞察力!!!!

    在修复方面,我认为根本上没有。如果我想在通过迁移更新联系人时创建活动,根据定义,没有 @current_user 联系。我会想办法解决这个问题,但坎大巴古肯定回答了我的问题。

    6 回复  |  直到 14 年前
        1
  •  3
  •   Harish Shetty    14 年前

    在更新联系人模型时,authlogic会话对象的创建方式似乎有些问题。你有没有观察者或前后过滤器 Contact 模型?

    来自的authlogic文档 Authlogic::Session::Base.activated?

    # 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 在修改 接触 模型实例,即:

    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
    

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

        2
  •  1
  •   Aaron Qian    14 年前

    我不确定这是否可行,但值得一试:

    替换此行:

    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_属性触发了此异常。 我猜它正处于验证阶段。所以我们使用update_属性跳过验证。

    如果仍然不起作用,则异常将在堆栈的下一层触发。 最坏的情况是,可以编写一些sql来更新模型。

        3
  •  0
  •   zetetic    14 年前

    这太奇怪了。我根本看不出authlogic是如何在迁移中被调用的。

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

    一个想法-你可以尝试:

    contact.business_id = contact.client_id
    contact.business_type = 'Client'
    contact.save_without_session_maintenance
    
        4
  •  0
  •   flopex    14 年前

    据我所知

     update_attributes(attributes) 
    

    只接受一个参数。 你可能是说

     update_attribute(name,value)
    
        5
  •  0
  •   Daniel Heath    14 年前

    注意:我假设你的应用程序中有一个名为user的模型。如果不是的话,我的意思是,无论哪个人用的是正宗的行为。

    短版本: 在迁移中添加以下内容:

    User.controller = true
    

    UserSession.controller = true
    

    如果解决了这个问题,那么问题是您的迁移正试图加载您的用户模型,这需要设置一个控制器来操作。

    看穿 http://github.com/binarylogic/authlogic/blob/v2.1.3/lib/authlogic/session/activation.rb 如果我所描述的不起作用,source可能是您想要开始的地方。

    编辑:

    添加到迁移的开始:

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

    这将禁用acts_as_authentic方法,这样您的模型就不会引入所有额外的内容。

        6
  •  -1
  •   Salil    14 年前

    这应该是如下,但没有检查。

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