【问题标题】:Creating a record for an association unobtrusively when attempting access?尝试访问时不显眼地为关联创建记录?
【发布时间】:2010-10-27 17:32:21
【问题描述】:

我在两个模型之间有一个简单的 has_one/belongs_to 关系。

这是我的应用程序中的一个新关联,因此有许多记录尚未创建关联记录。

在我的整个应用程序中,我假设模型具有关联并且我正在访问它的属性和方法。但是,由于关联不存在,所以我遇到了很多错误。

我想做的是在第一次通过它的任何方法和属性访问时,不显眼地动态构建关联的记录。记录中是否有数据并不重要,我只需要它存在,以便我调用的那些方法可以构建数据。

编辑:我不想在我尝试访问关系的所有实例上检查和创建记录,所以理想情况下这需要在模型本身上完成,而不是在我的控制器中的任何地方。

有什么想法吗?

谢谢!

【问题讨论】:

    标签: ruby-on-rails ruby model-view-controller unobtrusive


    【解决方案1】:

    在控制器中,您可以在 show 方法中添加类似的内容(未经测试,但它应该会给您一个想法:

    @thing = Thing.find params[:id]
    if @thing.other_thing.nil?
      @thing.other_thing = OtherThing.new.save!
      @thing.save!
    end
    

    这并不理想,您可以通过在 Thing 模型中放置一个方法来检查并创建相关模型而不是将其放入控制器中来清理它。

    另一种选择是创建一个用于访问other_thing 的新访问器,并根据需要创建它。

    但是,正确的做法可能是修复您的数据,无论是在迁移中还是直接正确地创建相关模型。

    【讨论】:

    • 正确,这并不理想。无论在何处访问,我都需要这样做。这就是为什么我需要在模型本身或关系中完成它。
    • 我为替代品添加了更多细节。
    【解决方案2】:

    直接的答案是覆盖关系的方法。调用时它将检查记录是否存在,如果不存在则创建它。

    但是,我建议您使用迁移来预先创建所有记录。

    【讨论】:

      【解决方案3】:

      我以前做过这种事情,但不是在模型层面。我已经在控制器级别使用 before_filter 完成了它,该过滤器在所有需要访问已存在或不存在的模型关联的方法之前运行。

      我刚刚意识到你可以在模型中使用 after_find 和 after_initialize 回调。

      你可以坚持:

      def after_initialize
         association.build if association.nil?
      end
      

      在您的模型中,它应该可以解决您的问题..(免责声明:未经我测试):)

      【讨论】:

        【解决方案4】:

        这就是我们最终解决的问题。它不是我写的(一位同事写的),但它通过了我为这个案例编写的之前失败的测试。

        def stats_with_create
          stats_without_create || create_stats
        end
        alias_method_chain :stats, :create
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多