我们在哪里声明 Rails 模型的属性?

whi*_*hat 5 ruby-on-rails

我来自 Java 背景,并且已经开始学习 Ruby on Rails。考虑http://guides.rubyonrails.org/active_record_basics.html 中提到的以下代码

class Product < ActiveRecord::Base
end
Run Code Online (Sandbox Code Playgroud)

该指南提到,这会创建一个映射到表 products 的模型 Product(使用 ruby​​ 的复数机制)。它还提到,“通过这样做,您还可以将表中每一行的列与模型实例的属性进行映射。”

但是我们没有在模型 Product 中声明任何属性。它怎么知道它的属性是什么?

一个假设:表的每个属性都作为模型的一个属性。这是真的吗?那么,我们是不是先创建SQL表呢?如果我稍后更改表(例如添加新列),它是否也会动态更改我的模型?

Ric*_*eck 5

它是这样工作的:

class Product < ActiveRecord::Base
Run Code Online (Sandbox Code Playgroud)

Product被子类化为ActiveRecord::Base(你知道从 Java 子类化,对吧?)。

ActiveRecord::Base可以在这里看到:

Active Record 对象不直接指定它们的属性,而是从 # 与它们链接的表定义中推断它们。添加、删除和更改属性 # 及其类型直接在数据库中完成。任何更改都会立即反映在 #Active Record 对象中。将给定的 Active Record 类绑定到某个数据库表的映射在最常见的情况下会自动发生,但可以在不常见的情况下被覆盖。

您可以通读其他代码;简而言之,这意味着ActiveRecord使用 SQL 模式来填充相应的属性。

——

因为您modelClass,ActiveRecord基本上会使用您的数据库中的值创建一系列setter/getter实例方法

当您调用所述类时,ActiveRecord::Base将使用数据库中的值填充相应的实例方法,允许您调用@product.name等。


D-s*_*ide 5

重要的区别在于我们讨论的是ActiveRecord模型,即 的子类(直接和间接)ActiveRecord::Base,使用其持久性机制的那些。以下内容不适用于一般的 Rails 模型。但话又说回来,对于非 AR 模型,这个问题没有意义:)

表的每个属性都作为模型的一个属性。这是真的吗?

是的。

那么,我们是不是先创建SQL表呢?

确切地。 rails g model创建一个模型文件和一个包含模型后面表声明的迁移。因此,在使用您的模型之前,您必须先运行迁移。

如果我稍后更改表(例如添加新列),它是否也会动态更改我的模型?

现在这很棘手。如果应用程序在更改后重新加载(例如,在开发模式中时不时会发生这种情况),这肯定是正确的,因为模型类将被重建。所以答案是肯定的,大多数时候

然而,这只是关于模型类的内部结构(在 eg 中可见Model.columns),您不必总是关心。获取数据时,结果集的所有列都将映射到模型对象的属性。因此,这甚至可以保留您在SELECTs 中指定的自定义列:

Thing.select(:id, "1 AS one").first.attributes
#> SELECT  "things"."id", 1 AS one FROM "things"  ORDER BY "things"."id" ASC LIMIT 1
# => {"id"=>1, "one"=>1}
Run Code Online (Sandbox Code Playgroud)