Rails:为什么模型方法不起作用?

时间:2010-01-03 18:09:05

标签: ruby-on-rails activerecord model

这是我第一次在这里发帖。我有一个问题,我可以不知何故无法解决。只是为了记录,我知道什么是实例和类方法(即使我可能完全不了解它们;-) 这是我的型号代码:

class Car < ActiveRecord::Base
has_many :drives
has_many :users, :through => :drives

def self.user_ids()
  ids = []
  self.users.each do |user|
    ids += user.id
  end
  ids
end

def self.common_times()
  start_times = []
  stop_times = []
  self.drives.each do |drive|
    drive.start_date_time += start_times
    drive.stop_date_time += stop_times
  end
  times = { :start => start_times.sort.last, :stop => stop_times.sort.first}
end

我想要的是使用汽车的所有用户的数组(我用它来检查给定用户是否已经连接到汽车以获取权限等。有没有更好的方法来检查两个数据集是否已连接而没有一直在做SQL查询?)以及他们喜欢的开始和停止时间。我需要比最新开始时间和最早停止时间的哈希值。 不知何故,user_ids方法有效(即使我认为它应该是一个实例方法)并且始终缺少common_times。如果我将它们定义为实例方法,我会遇到fixnum和数组的问题(比如“+”)。

user_id:
"TypeError: can't convert Fixnum into Array"

common_times:
"NoMethodError: You have a nil object when you didn't expect it!
You might have expected an instance of Array.
The error occurred while evaluating nil.+"

我猜最好的方法是让它们成为实例方法。但后来我需要以不同的方式引用其他模型作为用户和驱动器。

为什么即使将user_ids声明为类方法,user_ids也可以作为实例方法使用? 如何在实例方法中调用已加载的模型[c = Car.find(:all,:include =&gt;:drives)]?

有趣的是,只要它们是类方法,我就可以删除它们并重新启动mongrel,它们仍然可以工作(user_ids)而不工作(common_times)。

我现在很困惑,跳你可以帮助我。抱歉我的英语不好(我是德国人: - )

2 个答案:

答案 0 :(得分:3)

由于您的用户关联,Rails已预先构建了user_idsusers实例方法。使用@car.users应该是您最好的选择。

对于实例和类方法:实例方法用于特定对象,而类方法只是放在类名下面以方便使用。 @car.id是一个实例方法,因为它返回单个汽车的ID。 Cars.find是一个类方法,因为它独立于任何单个对象,而是在Cars类下分组以用于组织目的。 (它可以很容易地成为它自己的全局find_cars方法并且工作得很好,尽管这将是可怕的设计。)

所以你的两个方法都应该是实例方法,而Rails为你创建的第一个方法因为它非常爱你。

对于您的个别错误,使用<<运算符向数组添加对象,而不是加号。 Ruby认为你正在尝试添加两个数组,所以很困惑为什么你试图以与通常使用数组相同的方式使用Fixnum。尝试进行修复并查看是否仍然出现错误。

答案 1 :(得分:0)

让它工作(thnx @Matchu)。这是该方法的最终代码(不再是自制的user_ids; - )

def common_times()
  start_times = []
  stop_times = []
  drives.each do |drive|
    start_times << drive.start_date_time
    stop_times << drive.stop_date_time 
  end
  times = { :start => start_times.sort.last, :stop => stop_times.sort.first}
end 

最大的错误是切换的start_times&lt;&lt; drive.start_date_time

非常愚蠢的错误..

再次感谢!