【问题标题】:First Activerecord model missing attributes/methods第一个 Activerecord 模型缺少属性/方法
【发布时间】:2009-02-26 00:07:16
【问题描述】:

我遇到了一个非常奇怪的问题。我从数据库中获取了一组 Rails ActiveRecord 模型,但集合中的第一个模型没有模型属性/方法,只有标准的 ActiveRecord 基本方法。其余的具有所有属性。它只在我使用Passenger的生产debian服务器上执行此操作。它适用于 OS X 和 cygwin。

有什么想法吗?

谢谢, 凯文

【问题讨论】:

    标签: ruby-on-rails activerecord passenger


    【解决方案1】:

    这可能是您生产数据库中的错误数据。

    我会调高你的日志级别(生产环境不记录 SQL 查询),找到正在生成的查询,然后打开你的生产数据库并运行查询,看看它返回什么。

    【讨论】:

    • @Luke,数据库中的错误数据不应也不会影响单个对象属性访问器方法。它们与类焊接在一起,并以全有或全无的方式影响模型。
    • 好点。我想也许属性返回 nil,但如果它们根本不存在......那就是另一回事了。
    • @Luke,实际上我将它带回 Rails 2.2...查看 2.2 源代码,它似乎实际上检查的不是列,而是实际找到的列(请原谅我法语)来自数据库。
    • 是的,但是如果列在一行的结果集中,它们将在所有行的结果集中,不是吗?我认为你仍然是正确的。
    • 我们不知道凯文是如何(形成什么来源)建立他的@records;我不太确定“第一条记录不同”是否还有问题,我们会看到
    【解决方案2】:

    如果不进行一些调试,很难确定这一点,但我可能会考虑调查的一件事是线程问题。我相信,ActiveRecord 会在需要时动态定义这些方法,并且您可能会在访问第一个模型的过程中访问它。 Ruby 的“require”语句可能会出现类似的问题 - 如果您在一个线程中需要某些东西,那么当您尝试在另一个线程中访问它时,该类可能还没有完全定义。

    【讨论】:

      【解决方案3】:

      问题是我不想为 SQL Server 2005 使用正确的 freetds 版本。我使用的旧协议版本不支持超过 30 个字符的列名,这就是它找不到我的属性的原因正在打电话。它被截断了。在我的 freetds.conf 中更改它可以解决问题。感谢 Vlad 提供的所有故障排除帮助。

      【讨论】:

        【解决方案4】:

        当您说集合中的第一个模型没有模型属性/方法时,是因为您在尝试调用其中一个时遇到了NoMethodError 异常吗? p>

        在您尝试实际调用它们之前,模型对象没有属性方法(例如,当转储object.methods 的输出时)是正常的。当您尝试调用有问题的缺失方法之一时,将触发ActiveRecordmethod_missing 处理程序,并且如果方法名称与数据库中定义的列之一的名称匹配,则将动态创建该方法也不会有例外。如果没有发生这种情况,要么是因为对象属于错误的类(与您期望操作的模型不匹配),要么是因为插件或 gem 因method_missing 处理链中的行为不端而干扰。

        您能否将无属性对象实例的 self.class.name 的内容转储到日志中(logger.info 或 logger.info,具体取决于您的日志级别)?您还可以对生产环境和本地安装的 gem(和相应版本)进行审核吗?

        【讨论】:

        • 好的,第一个记录在被调用之前还没有方法/属性是有道理的。我正在使用一个聚合类,该类具有一组活动记录模型并调用一个方法并总结结果。请参阅下面的下一条评论
        • def method_missing(method, *args, &block) @records.inject(0) {|sum, record| sum + (eval("record.#{method.to_s}") || 0) } end 奇怪的是,当我为我的两个属性调用属性方法时,我只得到一个 method_missing 异常,其余的工作得很好。
        • 健全性检查:你能坚持一个记录器调用来验证记录的类型以及记录是否真的有相关的列吗?
        • @records.inject(0) {|总和,记录| logger.info("#{record.class}: #{record.columns.join(',')}"); sum + (eval("record.#{method.to_s}") || 0) }
        • 我不能为记录本身这样做,但我可以为类:MyClass.column_names,它包含我需要的所有列。我在我的 debian 生产服务器上运行 ruby​​ 1.8.5。奇怪的是它只是在吐两个属性。
        猜你喜欢
        • 1970-01-01
        • 2017-08-25
        • 2017-02-14
        • 1970-01-01
        • 2018-03-09
        • 2018-02-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多