跳至內容 跳至搜尋

Active Record 核心

命名空間
方法
#
A
C
D
E
F
H
I
L
N
P
R
S
V

屬性

[R] strict_loading_mode

類別公開方法

attributes_for_inspect

指定將包含在 `inspect` 方法輸出中的屬性。

Post.attributes_for_inspect = [:id, :title]
Post.first.inspect #=> "#<Post id: 1, title: "Hello, World!">"

當設定為 `:all` 時,`inspect` 將列出記錄的所有屬性。

Post.attributes_for_inspect = :all
Post.first.inspect #=> "#<Post id: 1, title: "Hello, World!", published_at: "2023-10-23 14:28:11 +0000">"
# File activerecord/lib/active_record/core.rb, line 119
class_attribute :attributes_for_inspect, instance_accessor: false, default: :all

configurations()

返回一個完全解析的 ActiveRecord::DatabaseConfigurations 物件。

# File activerecord/lib/active_record/core.rb, line 77
def self.configurations
  @@configurations
end

configurations=(config)

包含資料庫設定 - 通常儲存在 config/database.yml 中 - 作為一個 ActiveRecord::DatabaseConfigurations 物件。

例如,以下 database.yml…

development:
  adapter: sqlite3
  database: storage/development.sqlite3

production:
  adapter: sqlite3
  database: storage/production.sqlite3

…將導致 ActiveRecord::Base.configurations 看起來像這樣

#<ActiveRecord::DatabaseConfigurations:0x00007fd1acbdf800 @configurations=[
  #<ActiveRecord::DatabaseConfigurations::HashConfig:0x00007fd1acbded10 @env_name="development",
    @name="primary", @config={adapter: "sqlite3", database: "storage/development.sqlite3"}>,
  #<ActiveRecord::DatabaseConfigurations::HashConfig:0x00007fd1acbdea90 @env_name="production",
    @name="primary", @config={adapter: "sqlite3", database: "storage/production.sqlite3"}>
]>
# File activerecord/lib/active_record/core.rb, line 71
def self.configurations=(config)
  @@configurations = ActiveRecord::DatabaseConfigurations.new(config)
end

connection_handler()

# File activerecord/lib/active_record/core.rb, line 133
def self.connection_handler
  ActiveSupport::IsolatedExecutionState[:active_record_connection_handler] || default_connection_handler
end

connection_handler=(handler)

# File activerecord/lib/active_record/core.rb, line 137
def self.connection_handler=(handler)
  ActiveSupport::IsolatedExecutionState[:active_record_connection_handler] = handler
end

current_preventing_writes()

返回代表目前防止寫入設定的符號。

ActiveRecord::Base.connected_to(role: :reading) do
  ActiveRecord::Base.current_preventing_writes #=> true
end

ActiveRecord::Base.connected_to(role: :writing) do
  ActiveRecord::Base.current_preventing_writes #=> false
end
# File activerecord/lib/active_record/core.rb, line 196
def self.current_preventing_writes
  connected_to_stack.reverse_each do |hash|
    return hash[:prevent_writes] if !hash[:prevent_writes].nil? && hash[:klasses].include?(Base)
    return hash[:prevent_writes] if !hash[:prevent_writes].nil? && hash[:klasses].include?(connection_class_for_self)
  end

  false
end

current_role()

返回代表目前連接角色的符號。

ActiveRecord::Base.connected_to(role: :writing) do
  ActiveRecord::Base.current_role #=> :writing
end

ActiveRecord::Base.connected_to(role: :reading) do
  ActiveRecord::Base.current_role #=> :reading
end
# File activerecord/lib/active_record/core.rb, line 159
def self.current_role
  connected_to_stack.reverse_each do |hash|
    return hash[:role] if hash[:role] && hash[:klasses].include?(Base)
    return hash[:role] if hash[:role] && hash[:klasses].include?(connection_class_for_self)
  end

  default_role
end

current_shard()

返回代表目前連接分片的符號。

ActiveRecord::Base.connected_to(role: :reading) do
  ActiveRecord::Base.current_shard #=> :default
end

ActiveRecord::Base.connected_to(role: :writing, shard: :one) do
  ActiveRecord::Base.current_shard #=> :one
end
# File activerecord/lib/active_record/core.rb, line 177
def self.current_shard
  connected_to_stack.reverse_each do |hash|
    return hash[:shard] if hash[:shard] && hash[:klasses].include?(Base)
    return hash[:shard] if hash[:shard] && hash[:klasses].include?(connection_class_for_self)
  end

  default_shard
end

destroy_association_async_batch_size

指定 `dependent: :destroy_async` 關聯選項在單一背景作業中銷毀的記錄最大數量。當為 `nil`(預設值)時,所有依賴記錄將在單一背景作業中銷毀。如果指定,則要銷毀的記錄將被拆分為多個背景作業。

# File activerecord/lib/active_record/core.rb, line 47
class_attribute :destroy_association_async_batch_size, instance_writer: false, instance_predicate: false, default: nil

destroy_association_async_job()

用於在背景中銷毀關聯的作業類別。

# File activerecord/lib/active_record/core.rb, line 27
def self.destroy_association_async_job
  if _destroy_association_async_job.is_a?(String)
    self._destroy_association_async_job = _destroy_association_async_job.constantize
  end
  _destroy_association_async_job
rescue NameError => error
  raise NameError, "Unable to load destroy_association_async_job: #{error.message}"
end

enumerate_columns_in_select_statements

強制列舉 SELECT 語句中的所有欄位。例如 `SELECT first_name, last_name FROM ...` 而不是 `SELECT * FROM ...`。這可以避免在應用程式執行時向資料庫新增欄位時發生 `PreparedStatementCacheExpired` 錯誤。

# File activerecord/lib/active_record/core.rb, line 87
class_attribute :enumerate_columns_in_select_statements, instance_accessor: false, default: false

logger

接受符合 Log4r 介面或預設 Ruby `Logger` 類別的記錄器,然後將其傳遞給任何新的資料庫連線。您可以透過在 Active Record 模型類別或 Active Record 模型執行個體上呼叫 `logger` 來擷取此記錄器。

# File activerecord/lib/active_record/core.rb, line 22
class_attribute :logger, instance_writer: false

new(attributes = nil)

可以將新物件例項化為空的(不傳遞建構參數)或預設屬性但尚未儲存的(傳遞一個雜湊,其鍵名與關聯的表格欄位名稱匹配)。在這兩種情況下,有效的屬性鍵由關聯表格的欄位名稱決定 - 因此您不能擁有不屬於表格欄位一部分的屬性。

範例

# Instantiates a single new object
User.new(first_name: 'Jamie')
# File activerecord/lib/active_record/core.rb, line 460
def initialize(attributes = nil)
  @new_record = true
  @attributes = self.class._default_attributes.deep_dup

  init_internals
  initialize_internals_callback

  super

  yield self if block_given?
  _run_initialize_callbacks
end

執行個體公開方法

<=>(other_object)

允許對物件進行排序

# File activerecord/lib/active_record/core.rb, line 654
def <=>(other_object)
  if other_object.is_a?(self.class)
    to_key <=> other_object.to_key
  else
    super
  end
end

==(comparison_object)

如果 `comparison_object` 是同一個物件,或者 `comparison_object` 是同一類型且 `self` 有一個 ID 且它等於 `comparison_object.id`,則返回 true。

請注意,根據定義,新記錄與任何其他記錄都不同,除非其他記錄是接收者本身。此外,如果您使用 `select` 擷取現有記錄並省略 ID,則您需要自行負責,此謂詞將返回 false。

另請注意,銷毀記錄會在模型執行個體中保留其 ID,因此已刪除的模型仍然可以比較。

也稱為:eql?
# File activerecord/lib/active_record/core.rb, line 620
def ==(comparison_object)
  super ||
    comparison_object.instance_of?(self.class) &&
    primary_key_values_present? &&
    comparison_object.id == id
end

clone

與 Ruby 的 `clone` 方法相同。這是「淺」拷貝。請注意,您的屬性不會被拷貝。這表示修改副本的屬性將修改原始屬性,因為它們都指向同一個屬性雜湊。如果您需要屬性雜湊的拷貝,請使用 `dup` 方法。

user = User.first
new_user = user.clone
user.name               # => "Bob"
new_user.name = "Joe"
user.name               # => "Joe"

user.object_id == new_user.object_id            # => false
user.name.object_id == new_user.name.object_id  # => true

user.name.object_id == user.dup.name.object_id  # => false
# File activerecord/lib/active_record/core.rb, line 512
    

connection_handler()

# File activerecord/lib/active_record/core.rb, line 739
def connection_handler
  self.class.connection_handler
end

dup

複製的物件沒有分配 ID,並被視為新記錄。請注意,這是「淺」拷貝,因為它只拷貝物件的屬性,而不拷貝其關聯。「深」拷貝的範圍取決於應用程式,因此由應用程式根據其需要自行實作。`dup` 方法不保留時間戳記 (created|updated)_(at|on) 和鎖定欄位。

# File activerecord/lib/active_record/core.rb, line 529
    

encode_with(coder)

使用關於此記錄的屬性填充 `coder`,這些屬性應序列化。此方法中定義的 `coder` 結構保證與傳遞給 `init_with` 方法的 `coder` 結構匹配。

範例

class Post < ActiveRecord::Base
end
coder = {}
Post.new.encode_with(coder)
coder # => {"attributes" => {"id" => nil, ... }}
# File activerecord/lib/active_record/core.rb, line 576
def encode_with(coder)
  self.class.yaml_encoder.encode(@attributes, coder)
  coder["new_record"] = new_record?
  coder["active_record_yaml_version"] = 2
end

eql?(comparison_object)

別名:==

freeze()

複製並凍結屬性雜湊,以便即使在已刪除的記錄上仍然可以訪問關聯,但複製的模型不會被凍結。

# File activerecord/lib/active_record/core.rb, line 643
def freeze
  @attributes = @attributes.clone.freeze
  self
end

frozen?()

如果屬性雜湊已被凍結,則返回 true

# File activerecord/lib/active_record/core.rb, line 649
def frozen?
  @attributes.frozen?
end

full_inspect()

將記錄的所有屬性以格式良好的字串形式返回,忽略 .attributes_for_inspect

Post.first.full_inspect
#=> "#<Post id: 1, title: "Hello, World!", published_at: "2023-10-23 14:28:11 +0000">"
# File activerecord/lib/active_record/core.rb, line 763
def full_inspect
  inspect_with_attributes(all_attributes_for_inspect)
end

hash()

委託給 id 以允許兩個相同類型和 id 的記錄與以下內容一起使用

[ Person.find(1), Person.find(2), Person.find(3) ] & [ Person.find(1), Person.find(4) ] # => [ Person.find(1) ]
# File activerecord/lib/active_record/core.rb, line 630
def hash
  id = self.id

  if primary_key_values_present?
    self.class.hash ^ id.hash
  else
    super
  end
end

init_with(coder, &block)

coder 初始化一個空的模型物件。 coder 應該是先前使用 encode_with 編碼 Active Record 模型的結果。

class Post < ActiveRecord::Base
end

old_post = Post.new(title: "hello world")
coder = {}
old_post.encode_with(coder)

post = Post.allocate
post.init_with(coder)
post.title # => 'hello world'
# File activerecord/lib/active_record/core.rb, line 487
def init_with(coder, &block)
  coder = LegacyYamlAdapter.convert(coder)
  attributes = self.class.yaml_encoder.decode(coder)
  init_with_attributes(attributes, coder["new_record"], &block)
end

inspect()

將記錄的屬性以格式良好的字串形式返回。

Post.first.inspect
#=> "#<Post id: 1, title: "Hello, World!", published_at: "2023-10-23 14:28:11 +0000">"

可以通過設定 .attributes_for_inspect 來限制屬性。

Post.attributes_for_inspect = [:id, :title]
Post.first.inspect
#=> "#<Post id: 1, title: "Hello, World!">"
# File activerecord/lib/active_record/core.rb, line 753
def inspect
  inspect_with_attributes(attributes_for_inspect)
end

pretty_print(pp)

使用 PP 並將此記錄漂亮地列印到其中,允許您在需要 pp 時從 pp record 獲得良好的結果。

# File activerecord/lib/active_record/core.rb, line 769
def pretty_print(pp)
  return super if custom_inspect_method_defined?
  pp.object_address_group(self) do
    if @attributes
      attr_names = attributes_for_inspect.select { |name| _has_attribute?(name.to_s) }
      pp.seplist(attr_names, proc { pp.text "," }) do |attr_name|
        attr_name = attr_name.to_s
        pp.breakable " "
        pp.group(1) do
          pp.text attr_name
          pp.text ":"
          pp.breakable
          value = attribute_for_inspect(attr_name)
          pp.text value
        end
      end
    else
      pp.breakable " "
      pp.text "not initialized"
    end
  end
end

readonly!()

將此記錄標記為唯讀。

customer = Customer.first
customer.readonly!
customer.save # Raises an ActiveRecord::ReadOnlyRecord
# File activerecord/lib/active_record/core.rb, line 735
def readonly!
  @readonly = true
end

readonly?()

如果記錄是唯讀的,則返回 true

# File activerecord/lib/active_record/core.rb, line 671
def readonly?
  @readonly
end

slice(*methods)

返回一個雜湊,其中包含給定方法的名稱作為鍵,返回的值作為值。

topic = Topic.new(title: "Budget", author_name: "Jason")
topic.slice(:title, :author_name)
=> { "title" => "Budget", "author_name" => "Jason" }
# File activerecord/lib/active_record/core.rb, line 583
    

strict_loading!(value = true, mode: :all)

將記錄設定為 strict_loading 模式。如果記錄嘗試延遲載入關聯,則會引發錯誤。

user = User.first
user.strict_loading! # => true
user.address.city
=> ActiveRecord::StrictLoadingViolationError
user.comments.to_a
=> ActiveRecord::StrictLoadingViolationError

參數

  • value - 指定是否啟用或禁用嚴格載入的布林值。

  • :mode - 指定嚴格載入模式的 Symbol。預設為 :all。使用 :n_plus_one_only 模式將僅在延遲載入導致 n 加 1 查詢的關聯時引發錯誤。

範例

user = User.first
user.strict_loading!(false) # => false
user.address.city # => "Tatooine"
user.comments.to_a # => [#<Comment:0x00...]

user.strict_loading!(mode: :n_plus_one_only)
user.address.city # => "Tatooine"
user.comments.to_a # => [#<Comment:0x00...]
user.comments.first.ratings.to_a
=> ActiveRecord::StrictLoadingViolationError
# File activerecord/lib/active_record/core.rb, line 709
def strict_loading!(value = true, mode: :all)
  unless [:all, :n_plus_one_only].include?(mode)
    raise ArgumentError, "The :mode option must be one of [:all, :n_plus_one_only] but #{mode.inspect} was provided."
  end

  @strict_loading_mode = mode
  @strict_loading = value
end

strict_loading?()

如果記錄處於 strict_loading 模式,則返回 true

# File activerecord/lib/active_record/core.rb, line 676
def strict_loading?
  @strict_loading
end

strict_loading_all?()

如果記錄使用啟用 :all 模式的 strict_loading,則返回 true

# File activerecord/lib/active_record/core.rb, line 726
def strict_loading_all?
  @strict_loading_mode == :all
end

strict_loading_n_plus_one_only?()

如果記錄使用啟用 :n_plus_one_only 模式的 strict_loading,則返回 true

# File activerecord/lib/active_record/core.rb, line 721
def strict_loading_n_plus_one_only?
  @strict_loading_mode == :n_plus_one_only
end

values_at(*methods)

返回由給定方法返回的值的陣列。

topic = Topic.new(title: "Budget", author_name: "Jason")
topic.values_at(:title, :author_name)
=> ["Budget", "Jason"]
# File activerecord/lib/active_record/core.rb, line 598