跳到內容 跳到搜尋

Active Record 屬性方法

命名空間
方法
#
A
H
R
包含的模組

常量

RESTRICTED_CLASS_METHODS = %w(private public protected allocate new name superclass)
 

實體公開方法

[](attr_name)

傳回屬性值,認同於 attr_name,是在類型轉換後。(關於特定類型轉換行為的資訊,請參閱類型在 ActiveModel::Type 下面。)

class Person < ActiveRecord::Base
  belongs_to :organization
end

person = Person.new(name: "Francesco", date_of_birth: "2004-12-12")
person[:name]            # => "Francesco"
person[:date_of_birth]   # => Date.new(2004, 12, 12)
person[:organization_id] # => nil

當屬性遺失時,會引發 ActiveModel::MissingAttributeError。不過,請注意,id 屬性永不被視為遺失。

person = Person.select(:name).first
person[:name]            # => "Francesco"
person[:date_of_birth]   # => ActiveModel::MissingAttributeError: missing attribute 'date_of_birth' for Person
person[:organization_id] # => ActiveModel::MissingAttributeError: missing attribute 'organization_id' for Person
person[:id]              # => nil
# File activerecord/lib/active_record/attribute_methods.rb, line 414
def [](attr_name)
  read_attribute(attr_name) { |n| missing_attribute(n, caller) }
end

[]=(attr_name, value)

使用指定的 value 更新認同於 attr_name 的屬性。屬性值會在讀取時類型轉換。

class Person < ActiveRecord::Base
end

person = Person.new
person[:date_of_birth] = "2004-12-12"
person[:date_of_birth] # => Date.new(2004, 12, 12)
# File activerecord/lib/active_record/attribute_methods.rb, line 427
def []=(attr_name, value)
  write_attribute(attr_name, value)
end

accessed_fields()

傳回已從此模型讀取到的所有資料庫欄位名稱。這項功能在開發階段中會很有幫助,因為可以藉此決定需要選取哪些欄位。對於效能至上的頁面來說,僅選取必要的欄位可能是輕而易舉就能提升效能的方法(假設您並未使用模型中的所有欄位)。

例如

class PostsController < ActionController::Base
  after_action :print_accessed_fields, only: :index

  def index
    @posts = Post.all
  end

  private
    def print_accessed_fields
      p @posts.first.accessed_fields
    end
end

這讓您可以快速變更程式碼為

class PostsController < ActionController::Base
  def index
    @posts = Post.select(:id, :title, :author_id, :updated_at)
  end
end
# File activerecord/lib/active_record/attribute_methods.rb, line 459
def accessed_fields
  @attributes.accessed
end

attribute_for_inspect(attr_name)

傳回屬性 attr_name 值的 #inspect 類似字串。 String 屬性會被截斷至 50 個字元。其他屬性則回傳 #inspect 的值,且不進行修改。

person = Person.create!(name: 'David Heinemeier Hansson ' * 3)

person.attribute_for_inspect(:name)
# => "\"David Heinemeier Hansson David Heinemeier Hansson ...\""

person.attribute_for_inspect(:created_at)
# => "\"2012-10-22 00:15:07.000000000 +0000\""

person.attribute_for_inspect(:tag_ids)
# => "[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]"
# File activerecord/lib/active_record/attribute_methods.rb, line 364
def attribute_for_inspect(attr_name)
  attr_name = attr_name.to_s
  attr_name = self.class.attribute_aliases[attr_name] || attr_name
  value = _read_attribute(attr_name)
  format_for_inspect(attr_name, value)
end

attribute_names()

傳回此物件可用的屬性名稱陣列。

class Person < ActiveRecord::Base
end

person = Person.new
person.attribute_names
# => ["id", "created_at", "updated_at", "name", "age"]
# File activerecord/lib/active_record/attribute_methods.rb, line 333
def attribute_names
  @attributes.keys
end

attribute_present?(attr_name)

如果已由使用者或資料庫載入設定指定的 attribute,而且該資料既不是 nil 也不是 empty?(後者僅適用於會回應 empty? 的物件,最顯著的範例就是字串),則會傳回 true。否則,會傳回 false。請注意,布林屬性會始終傳回 true

class Task < ActiveRecord::Base
end

task = Task.new(title: '', is_done: false)
task.attribute_present?(:title)   # => false
task.attribute_present?(:is_done) # => true
task.title = 'Buy milk'
task.is_done = true
task.attribute_present?(:title)   # => true
task.attribute_present?(:is_done) # => true
# File activerecord/lib/active_record/attribute_methods.rb, line 386
def attribute_present?(attr_name)
  attr_name = attr_name.to_s
  attr_name = self.class.attribute_aliases[attr_name] || attr_name
  value = _read_attribute(attr_name)
  !value.nil? && !(value.respond_to?(:empty?) && value.empty?)
end

attributes()

傳回雜湊,其中包含所有屬性,且其名稱做為金鑰,而屬性的值做為值。

class Person < ActiveRecord::Base
end

person = Person.create(name: 'Francesco', age: 22)
person.attributes
# => {"id"=>3, "created_at"=>Sun, 21 Oct 2012 04:53:04, "updated_at"=>Sun, 21 Oct 2012 04:53:04, "name"=>"Francesco", "age"=>22}
# File activerecord/lib/active_record/attribute_methods.rb, line 345
def attributes
  @attributes.to_hash
end

has_attribute?(attr_name)

如果給定的屬性在屬性雜湊中,則會傳回 true,否則會傳回 false

class Person < ActiveRecord::Base
  alias_attribute :new_name, :name
end

person = Person.new
person.has_attribute?(:name)     # => true
person.has_attribute?(:new_name) # => true
person.has_attribute?('age')     # => true
person.has_attribute?(:nothing)  # => false
# File activerecord/lib/active_record/attribute_methods.rb, line 315
def has_attribute?(attr_name)
  attr_name = attr_name.to_s
  attr_name = self.class.attribute_aliases[attr_name] || attr_name
  @attributes.key?(attr_name)
end

respond_to?(name, include_private = false)

具有名稱屬性的 Person 物件可以詢問 person.respond_to?(:name)person.respond_to?(:name=)person.respond_to?(:name?),且所有這些都會回傳 true。它也會定義屬性方法(如果尚未產生這些屬性方法的話)。

class Person < ActiveRecord::Base
end

person = Person.new
person.respond_to?(:name)    # => true
person.respond_to?(:name=)   # => true
person.respond_to?(:name?)   # => true
person.respond_to?('age')    # => true
person.respond_to?('age=')   # => true
person.respond_to?('age?')   # => true
person.respond_to?(:nothing) # => false
# File activerecord/lib/active_record/attribute_methods.rb, line 290
def respond_to?(name, include_private = false)
  return false unless super

  # If the result is true then check for the select case.
  # For queries selecting a subset of columns, return false for unselected columns.
  if @attributes
    if name = self.class.symbol_column_to_string(name.to_sym)
      return _has_attribute?(name)
    end
  end

  true
end