我在我的一个数据库表中添加了一些列,然后填充这些列:
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肯定回答了我的问题。
答案 0 :(得分:3)
在更新Contact模型时,如何创建Authlogic会话对象。在Contact
模型的过滤器之前/之后是否有任何观察者?
来自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
模型实例之前设置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'