跳到内容

Ruby on Rails/ActiveRecord/属性

来自维基教科书,开放的书籍,为开放的世界

ActiveRecord 属性是根据底层数据库模式自动确定的。

基本用法

[编辑 | 编辑源代码]

表中的所有列都可通过 ActiveRecord 模型的方法访问。例如

考虑以下迁移

# 20090409120944_create_products.rb
class CreateProducts < ActiveRecord::Migration
  def self.up
    create_table :products do |t|
      t.string :name
      t.float :price
      t.integer :amount
    end
  end
#...
end

由于 Rails 为我们创建了一个主键并将其命名为 "id",因此我们已经可以在数据库中搜索它。我们可以通过内置控制台与数据库交互

 ruby script/console

它为我们提供了一个控制台,让我们可以与 Rails 进行通信。

在我们能够从数据库中选择数据之前,现在该插入一些产品了

 >> Product.new(:name => "my book", :price => 14.99, :amount => 4).save

如果一切顺利,Rails 将向您显示=>true在控制台中... 让我们添加更多产品

 >> Product.new(:name => "my movie", :price => 4.89 :amount => 1).save
 >> Product.new(:name => "my cd", :price => 9.98, :amount => 12).save

现在我们在数据库中有 3 个产品,从 1 到 3 ...

所以让我们选择第一个条目

 >>Product.find(1)

然后 Rails 会告诉你它为这个 id 找到了什么(记住:find 只有在存在 Rails 生成的 id 作为主键时才有效)

 => #<Product: id=1, name="my book" ..... >

所以我们能够告诉 Rails 查找具有特定 id 的条目。但是,当我们在数据库中有数千个条目时会发生什么?我们无法记住每个产品的 id,因此 Rails 提供了一个非常巧妙的解决方案

 >>Product.find_by_name("my book")
 => #<Product: id=1, name="my book" ..... >

然后 Rails 给出了我们想要的结果。这不仅适用于名称,也适用于数据库中的所有列。我们也可以使用.find_by_price或者.find_by_amount

或者您可以根据其 id 搜索多个产品

>>Product.find(1,3)

=> #<Product: id=1, name="my book" ..... ><Product: id=3, name="my cd" ..... >

您也可以搜索所有产品

 >>Product.all

或者

 >>Products.find(:all)

用于表中的第一个或最后一个产品

 >>Product.first/last

或者

 >>Product.find(:first/:last)

如果您想对数据进行更多控制,可以使用许多内置选项或使用自定义 SQL。让我们尝试以降序(3,2,1)查找数据

 >>Product.all(:order => "id DESC")

或者

 >>Product.find(:all, :order => "id DESC")

将为您提供所有产品,从最后一个插入的 id 开始 - 在我们的案例中:3


当我们查询数据库时,我们得到很多我们并不真正感兴趣的信息,例如 "created_at" 和 "updated_at" 列。我们只想看一下我们的 id 和名称,所以我们可以使用

 >>Product.all(:select => "id, name")

或者

 >>Product.find(:all, :select => "id, name")

此方法将只显示产品的名称和 id,使其更易读。

在搜索数据时,请记住,您可以根据自己的喜好组合所有这些方法。要查看更多可能性,请查看 RoR 指南API

覆盖属性

[编辑 | 编辑源代码]

您可以覆盖 ActiveRecord 模型类中的任何访问器方法,以添加逻辑。例如

  class Product
    def name
      self[:name] || 'Unknown'
    end
  end
 p = Product.new
 p.name
 => "Unknown"
 p.name = 'my disk'
 p.name
 => "my disk"

您可以通过self[attribute_name](获取)或self[attribute_name]=(设置)。

华夏公益教科书