2

我有一个关于 Rails 及其关系查询构建器的问题,特别是如何为相关调用转换骆驼大小写。

相关代码

class CustomerPlan < ActiveRecord::Base
  attr_accessible :customer_id, :plan_id, :startDate, :user_id

  has_many :planActions
end

class PlanAction < ActiveRecord::Base
  attr_accessible :actionType_id, :customerPlan_id, :notes, :timeSpent

  belongs_to :customerPlan
  belongs_to :actionType
end

getter 和 setter 工作得很好,例如plan_action.actionType.name可以正确地从相关模型中提取。但是customer_plan.planActions.each返回错误:

SQLite3::SQLException: no such column: plan_actions.customer_plan_id: 
  SELECT "plan_actions".* 
    FROM "plan_actions"  
    WHERE "plan_actions"."customer_plan_id" = 1

该列在数据库中定义为customerPlan_id,我使用它是不是错了?它适用于所有其他电话,我所有其他关系都很好。甚至 PlanAction -> CustomerPlan。

我浏览了所有文档,并搜索了我知道的所有其他来源。更改我的列很简单,我只想知道这里发生了什么。

感谢您的时间!


对此的快速解决方法是显式设置foreign_key。

has_many :planActions, :foreign_key => "customerPlan_id", :class_name => "PlanAction"

不过,我认为我在某处遗漏了一些模型命名约定,只是似乎无法弄清楚是什么。

4

2 回答 2

1

对于 DB 列名,Rails 约定是使用小写字母和由下划线分隔的单词(例如author_idcomments_countupdated_at等)。

我强烈建议您遵守 Rails 约定。这将使您的生活更轻松。要将其更改为 rails 约定,只需创建迁移以将列重命名为适当的样式。

但是,如果您确实想为列名使用自定义样式,rails 会在has_many:foreign_key关系中提供选项来指定预期的外部列名:

class CustomerPlan < ActiveRecord::Base
  has_many :plan_actions, :foreign_key => 'customerPlan_id'
end

alias_attribute如果您想使用与实际 DB 列名称不同的模型属性名称,也可以使用宏为列名称设置别名。但正如我所提到的,我建议尽可能地遵守 Rails 约定。你以后会感谢我的。

于 2012-10-13T00:49:03.190 回答
0

Rails 有 3 种基本的命名方案。

一个是常数,它是ALL_UPPERCASE_SEPARATED_BY_UNDERSCORES.

一个是用于 Classes 的,它是AllCamelCaseWithNoUnderscores.

一种是用于变量和方法名的,一种是all_lowercase_separated_by_underscores.

之所以采用这种方式,不仅是为了保持一致性,还因为它使用这些方法在它们之间自由转换。

因此,要使您发布的代码更符合 Rails-y:

class CustomerPlan < ActiveRecord::Base
  attr_accessible :customer_id, :plan_id, :start_date, :user_id

  has_many :plan_actions
end

class PlanAction < ActiveRecord::Base
  attr_accessible :action_type_id, :customer_plan_id, :notes, :time_spent

  belongs_to :customer_plan
  belongs_to :action_type
end
于 2012-10-13T03:20:15.743 回答