Ruby 当通过HAML调用我的对象时,它会尝试触发活动记录,而不仅仅是调用一个方法

Ruby 当通过HAML调用我的对象时,它会尝试触发活动记录,而不仅仅是调用一个方法,ruby,activerecord,methods,sinatra,haml,Ruby,Activerecord,Methods,Sinatra,Haml,我在构造发送给用户的电子邮件时调用了以下HAML代码段 %p Please <a href="#{base_url}/verify/#{user.primary_email.email}/#{user.registration_token}">click this link to confirm your email address</a>. You will then be logged in and can choose a password and contin

我在构造发送给用户的电子邮件时调用了以下HAML代码段

%p
  Please <a href="#{base_url}/verify/#{user.primary_email.email}/#{user.registration_token}">click this link to confirm your email address</a>. You will then be logged in and can choose a password and continue the process of confirming your identity.
但是我得到了错误信息

NoMethodError - undefined method `primary_email' for #<ActiveRecord::Relation:0x10f0d3a58>:
 /Users/davesag/src/git/showpony3/rack/ruby/1.8/gems/activerecord-3.0.7/lib/active_record/relation.rb:374:in `method_missing'
 ./views/user_notifications/confirm_registration.haml:30:in `__tilt_2272398620'
 ./views/user_notifications/confirm_registration.haml:-7:in `instance_eval'
 ./views/user_notifications/confirm_registration.haml:-7:in `__tilt_2272398620'
 /Users/davesag/src/git/showpony3/rack/ruby/1.8/gems/tilt-1.3.2/lib/tilt/template.rb:140:in `call'
 /Users/davesag/src/git/showpony3/rack/ruby/1.8/gems/tilt-1.3.2/lib/tilt/template.rb:140:in `cached_evaluate'
 /Users/davesag/src/git/showpony3/rack/ruby/1.8/gems/tilt-1.3.2/lib/tilt/template.rb:127:in `evaluate'
 /Users/davesag/src/git/showpony3/rack/ruby/1.8/gems/tilt-1.3.2/lib/tilt/haml.rb:24:in `evaluate'
 /Users/davesag/src/git/showpony3/rack/ruby/1.8/gems/tilt-1.3.2/lib/tilt/template.rb:76:in `render'
 /Users/davesag/src/git/showpony3/rack/ruby/1.8/gems/sinatra-1.2.6/lib/sinatra/base.rb:563:in `render'
 /Users/davesag/src/git/showpony3/rack/ruby/1.8/gems/sinatra-1.2.6/lib/sinatra/base.rb:463:in `haml'
 ./showpony.rb:256:in `build_messge_for'
这很好

当我触发发送此模板时,它会工作一次,然后在同一请求中的第二次发送失败。(当我通过浏览器进行测试时,管理员用户和测试用户都会收到相同的通知电子邮件)

更奇怪的是,在我的日志中,我看到了对主电子邮件方法的调用。(实际编辑的电子邮件)


仔细检查您的错误表明,您试图调用的“primary_email”方法不是在ActiveRecord对象上,而是在Relation对象上

例如,如果您以以下方式获取“user”变量,则可能会发生这种情况

user = User.where("some conditions")
因为“where”返回的不是ActiveRecords数组,而是关系对象

要获得实际的AR对象,可以尝试

user = User.where("some conditions").first


我的第一个想法是重构:

result = self.emails.first(:conditions => {:primary => true})
致:

但是,我不确定这是你的问题的原因

另外,请尝试在方法中输出user.attributes:

def primary_email()
  puts self.attributes.sort
  result = self.emails.first(:conditions => {:primary => true})
如果这还不能说明问题,我想你也必须给我们你的用户、组织和电子邮件模型的代码


您还可以检查您的数据库,以验证是否没有旧迁移留下的散列,也许?

这听起来很疯狂,但请尝试在.haml文件中重写haml代码,以便利用使用缩进将其写入多行:

%p
  - email = user.primary_email.email
    Please 
    %a{:href=>"#{base_url}/verify/#{email}/#{user.registration_token}"}
      click this link to confirm your email address...
    You will then be...

别忘了@instance您的变量

,这很有趣。我可以通过
.where
确认用户未被加载,但在本例中,用户正在创建并保存到数组中。但奇怪的是,只有当我的列表中有多个
User
对象时才会发生错误。数组中的第一个
用户
工作正常。通知电子邮件发送完美,没有任何问题。但是第二个
用户
失败,因为它似乎是一个
ActiveRecord::Relation
对象,不是
User
对象。好的,只是为了确保我更改了代码,使其仅在数组中存储用户名,然后在生成注册电子邮件时,它会在用户名数组中循环,并通过
p=User加载用户对象。按用户名查找(pname)
只是为了确保。然而,我得到了同样的结果。第一个
p
很好,第二个是
关系
而不是
用户
,但仅当通过
HAML
加载时才出现。您确定仅当从HAML模板调用
主电子邮件
方法时才会出现此问题吗?如果你在
这些人中提取这封电子邮件,每个人都会循环并将其与
{:user=>p}
一起传递到模板,它会正常工作吗?嗨@cug你的问题让我走上了一条有趣的道路。似乎正在发生的事情实际上与我如何找到
组织
管理员
用户有关。在我的
HAML
中,我可以通过
o=user.organization
从用户那里获得组织,然后通过我调用
a=o.get\u admin
来解决问题。
get\u admin
方法通过
return self.users.with\u role('admin')
获取管理员用户。这就是我得到返回的
关系的地方。没有为第一个用户调用它的原因是第一个用户是管理员,因此没有执行
haml
位。所以我试着只添加
。首先
到该查询的末尾,但随后出现了一个
SQL
错误。嘿@suranyami,主\u电子邮件被称为OK,并且大部分时间工作正常。正是在从
HAML
渲染操作(即从
Tilt
)调用它的实例中,它突然变成了
关系
,而不是
用户
。不管怎样,我还是做了您建议的更改,并且吐出了
self.attributes.sort
,表明在调用该方法时它确实起作用。问题比唉还严重。
primary\u email
方法没有从
HAML
模板中调用,尽管它在紧靠它前面的代码行中被愉快地调用。
user = User.where("some conditions").first
user = User.find("some conditions")
result = self.emails.first(:conditions => {:primary => true})
result = self.emails.where(:primary => true).first
def primary_email()
  puts self.attributes.sort
  result = self.emails.first(:conditions => {:primary => true})
%p
  - email = user.primary_email.email
    Please 
    %a{:href=>"#{base_url}/verify/#{email}/#{user.registration_token}"}
      click this link to confirm your email address...
    You will then be...