【问题标题】:Rails Seed confusionRails 种子混淆
【发布时间】:2011-06-01 23:59:19
【问题描述】:

我在使用 seed.rb 播种我的数据库时遇到问题,特别是在涉及表关系的地方。

以下是代码示例:

# seed.rb
user = User.find_or_create_by_login(  
  :login => "myname",  
  :email => "myname@gmail.com",  
  :user_type => "Admin",  
  :password => "admin",  
  :password_confirmation => "admin")

project = Project.find_or_create_by_user_id(
  :user_id => user.id,
  :name => "Test Project")

创建项目时(以及我在上面遗漏的其他不相关参数),user_id 为空。我怎样才能让它工作?


这是我在如此简单的事情中见过的最奇怪的行为。在我的种子文件中,我创建了大约 8 个表,其中一些嵌套了 3-4 层(即用户 has_many 项目;项目 has_many 任务等)。

当我如上所述调用用户user 并在此之后多次引用user.id 时,它只能工作一次!我尝试在创建每条新记录之前添加 [user.reload] 但无济于事。我不认为这对任何人都有意义,但是这里有什么可能性吗?谢谢大家。

【问题讨论】:

    标签: ruby-on-rails ruby-on-rails-3 seed


    【解决方案1】:

    我发现了问题所在。未填充的字段未在其各自模型的attr_accessible 中明确列出。列出的字段已正确保存。

    非常感谢大家的帮助。

    【讨论】:

      【解决方案2】:

      代码很好,是find_or_create 的正确语法。正如其他人所说,最可能的问题是用户无效。如果用户无效,尝试调用user.reload 会使其崩溃,因此会使问题更加明显,但是您从中得到的错误将毫无用处(它会抱怨找不到没有 id 的用户)。

      不幸的是,find_or_create 在无效时不能作为 bang 方法引发异常,因此最好的办法可能是引发错误并在尝试创建用户后输出错误:

      user = User.find_or_create_by_login(:login => "myname")
      raise "User is invalid: #{user.errors.full_messages}" unless user.valid?
      

      【讨论】:

      • 出于好奇,你们是否在某个地方找到了 find_or_create 文档?当然,新年快乐!
      • Rails 指南没有提到哈希语法,而是“基于动态属性的查找器”:这里是 apidock.com/rails/v3.0.0/ActiveRecord/Base
      • 是的,AR::Base 中的文档就是它的全部。如果您有兴趣深入挖掘,它是 AR 提供魔术方法的 method_missing 的一部分(在 base.rb 和 Association_collection.rb 中,取决于您调用它的内容),然后它使用 DynamicFinderMatch类来确定您尝试使用哪种类型的魔术方法。新年快乐!
      • +1 解决了我的问题,为我提供调试输出以跟踪问题!
      【解决方案3】:

      成功创建用户?如果是这样..尝试 user.reload 如果不是。这可能是错误

      【讨论】:

      • user.reload 去哪儿了?使用种子文件时会产生什么行为?
      【解决方案4】:

      您确定您的用户已保存吗?我认为find_or_create_by_XX 的正确语法是Blog.find_or_create_by_title("Some Blog")。如果您需要传递更多数据,您需要先使用find_or_initialize,然后单独设置其他数据。

      松散相关的线程:Rails find_or_create by more than one attribute?

      --编辑

      将数据作为哈希传递给find_or_create_by_XX 似乎也可以。文档位于“基于动态属性的查找器”下http://apidock.com/rails/v3.0.0/ActiveRecord/Base

      【讨论】:

      • 感谢 Heikki - 我在问题中显示的代码使人们能够通过一组参数查找或创建记录,并且如果找到它们,它会插入更多值。 find_or_create 在某些情况下非常强大。
      【解决方案5】:

      试试这个 使用User.find_or_create 而不是User.find_or_create_by_login。 似乎您的用户对象未保存。 或者在分配 user.id 之前执行 user.reload

      user = User.find_or_create(  
        :login => "myname",  
        :email => "myname@gmail.com",  
        :user_type => "Admin",  
        :password => "admin",  
        :password_confirmation => "admin")
      
      [user.reload]
      
      project = Project.find_or_create_by_user_id(  :user_id => user.id,
        :name => "Test Project")
      

      【讨论】:

      • User.find_or_create 真的有用吗?它如何确定该用户是否存在?
      • 感谢您澄清 Yise 提到的 user.reload 点。我也很困惑它将使用什么标准来执行该查找。
      • 至少 Rails 3 说 NoMethodError: undefined method find_or_create'`。
      猜你喜欢
      • 1970-01-01
      • 2011-12-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-10-22
      • 1970-01-01
      • 1970-01-01
      • 2014-08-15
      相关资源
      最近更新 更多