Active Record Basics

翻译自SUN官方文档
Topics
主题
• What is Active Record?
什么是Active Record?
• ActiveRecord Object Creation
ActiveRecord对象创建
• Find operation
Find方法
• Dynamic Attribute-based Finders
动态地基于属性的Finder
• Validation
验证
• Migration
迁移
• Callbacks
回滚
• Exception Handling
异常控制

What is Active Record?
What is Active Record?
• Active Record is a Ruby library that provides mapping between business objects and database tables
Active Record是一个提供业务对象和数据库表之间映射关系的Ruby库
> Accessing, saving, creating, updating operations in your Rails code are performed by Active Record
Rails代码里的增删改查操作由Active Record执行
• It‘s an implementation of the object-relational mapping (ORM) pattern by the same name as described by Martin Fowler:
它实现了对象关系映射(ORM)模型,通过相同的命名由Martin Fowler:
> "An object that wraps a row in a database table or view, encapsulates the database access, and adds domain logic on that data."
“一个对象,就是数据库表或视图里的一行,封装了数据库链接,和数据的逻辑域”
• Contains domain logic
包含逻辑域

Major Features
主要特性
• Automated mapping between classes and tables, attributes and columns.
在类和表,属性和列之间自动映射
• Validation rules that can differ for new or existing objects.
验证规则可以区别新旧对象
• Callbacks as methods or queues on the entire lifecycle (instantiation, saving, destroying, validating, etc).
方法或队列的在一个完整生命周期里可以回滚
• Observers for the entire lifecycle
生命周期的观察者
• Transaction support on both a database and object level.
数据库和对象层都有事务支持
• Reflections on columns, associations, and aggregations
反射
• Direct manipulation (instead of service invocation)
直接操作
• Database abstraction through simple adapters (~100 lines) with a shared connector
通过简单的adapter实现数据抽象
• Logging support for Log4r and Logger
Log4r和Logger的日志支持
• Associations between objects controlled by simple meta-programming macros.
通过简单的元编程实现对象控制的联合
• Aggregations of value objects controlled by simple meta-programming macros.
通过简单的元编程实现对象控制的聚合
• Inheritance hierarchies
继承的分层

Automatic Mapping between Classes and Tables
类和表之间的自动映射
Mapping between Classes and Tables
• Class definition below is automatically mapped to the table named “products”
下面的类自动映射到命名为“products”的表
  1. class Product < ActiveRecord::Base
  2. end
• Schema of “products” table
数据模型的“products”表
  1. CREATE TABLE products (
  2. id int(11) NOT NULL auto_increment,
  3. name varchar(255),
  4. PRIMARY KEY (id)
  5. );
Active Record Definition & Domain Logic
Active Record定义和逻辑域
• Class definition below is automatically mapped to the table named “products”
class Product < ActiveRecord::Base
end
• Active Record typically contain domain logic
典型的Active Record包括逻辑域
  1. class Product < ActiveRecord::Base
  2. def my_business_method
  3. # Whatever business logic
  4. end
  5. end
Attributes
属性
• Active Record objects don‘t specify their attributes directly, but rather infer them from the table definition with which they‘re linked.
Active Record对象并不直接指定他们的属性,而是从相关的表的定义中推断
• Adding, removing, and changing attributes and their type is done directly in the database.
添加,删除和改变属性和类型会直接在数据库里完成
• Any change is instantly reflected in the Active Record objects.
任何改变将立刻在Active Record里产生影响

ActiveRecord Object Creation, Update, Delete
ActiveRecord对象的创建,修改和删除
ActiveRecord Objects Can Be Created in 3 Different Ways
ActiveRecord对象能够由三种途径创建
• Constructor parameters in a hash
构造函数在一个hash
  1. user = User.new(:name => "David":occupation => "Artist")
• Use block initialization
用block初始化
  1. user = User.new do |u|
  2. u.name = "David"
  3. u.occupation = "Code Artist"
  4. end
• Create a bare object and then set attributes
创建一个裸体对象,然后设置属性
  1. user = User.new
  2. user.name = "David"
  3. user.occupation = "Code Artist"
ActiveRecord Objects Can Be Saved
ActiveRecord对象能够被保存
• Use save instance method - a row is added to the table
用save方法 - 一行将被添加到数据库
  1. user = User.new(:name => "David":occupation => "Artist")
  2. user.save

ActiveRecord Find Operation
ActiveRecord的Find操作
find Method
find方法
• find is a class method
find是一个类方法
> In the same way, new and create are class methods
同理,new和create也是类方法
> You use it with a ActiveRecord class (not with an object instance)
你使用它用ActiveRecord类(而不是实例变量)
>Product.find(..)

Find Operation
Find操作
• Find operates with four different retrieval approaches:
Find操作有四个不同的实现方法:
> Find by id - This can either be a specific id (1), a list of ids (1, 5, 6), or an array of ids ([5, 6, 10]). If no record can be found for all of the listed ids, then RecordNotFound will be raised.
Find by id - 可以是一个指定的id(1),一个id列表(1, 5, 6), 或者是一个id数组([5, 6, 10]).如果一条记录也找不到,会抛出RecordNotFound异常
> Find first - This will return the first record matched by the options used
Find first - 返回第一条匹配的记录
> Find last - This will return the last record matched by the options used.
Find last - 返回最后一条匹配的记录
> Find all - This will return all the records matched by the options used. If no records are found, an empty array is returned.
Find all - 返回所有匹配的记录。如果找不到记录,返回一个空数组

Find Criteria
Find准则
• :conditions - An SQL fragment like "administrator = 1" or [ "user_name = ?", username ]
:conditions - 一条SQL语句,比如"administrator = 1" 或者 [ "user_name = ?", username ]
• :order
• :group - An attribute name by which the result should be grouped. Uses the GROUP BY SQL-clause.
:group - 一个需要被分组的属性名。用GROUP BY SQL语句
• :limit - An integer determining the limit on the number of rows that should be returned.
:limit - 给一个整数决定需要返回的行数
• :offset - An integer determining the offset from where the rows should be fetched.
:offset - 给一个整数决定哪几行被分离。
• :joins - Either an SQL fragment for additional joins like "LEFT JOIN comments ON comments.post_id = id" (rarely needed) or named associations in the same form used for the :include option, which will perform an INNER JOIN on the associated table(s).
:joins - 附加一个SQL语句,如"LEFT JOIN comments ON comments.post_id = id"(必须的)或者由同一个格式命名
• :include - Names associations that should be loaded alongside. The symbols named refer to already defined associations.
• :select - By default, this is "*" as in "SELECT * FROM", but can be changed if you, for example, want to do a join but not include the joined columns.
• :from - By default, this is the table name of the class, but can be changed to an alternate table name (or even the name of a database view).
• :readonly - Mark the returned records read-only so they cannot be saved or updated.
• :lock - An SQL fragment like "FOR UPDATE" or "LOCK IN SHARE MODE". :lock => true gives connection‘s default exclusive lock, usually "FOR UPDATE".
Examples: Find by id
  1. Person.find(1) # returns the object for ID = 1
  2. Person.find(1, 2, 6) # returns an array for objects with IDs in (1, 2, 6)
  3. Person.find([7, 17]) # returns an array for objects with IDs in (7, 17)
  4. Person.find([1]) # returns an array for the object with ID = 1
  5. Person.find(1, :conditions => "administrator = 1",
  6. :order => "created_on DESC")
Examples: Find first
  1. Person.find(:first# returns the first object fetched
  2. # by SELECT * FROM people
  3. Person.find(:first:conditions => [ "user_name = ?", user_name])
  4. Person.find(:first:order => "created_on DESC":offset => 5)
Example: Find all
  1. Person.find(:all# returns an array of objects for all the
  2. rows fetched by SELECT * FROM people
  3. Person.find(:all:conditions => [ "category IN (?)",
  4. categories], :limit => 50)
  5. Person.find(:all:conditions => { :friends => ["Bob",
  6. "Steve""Fred"] }
  7. Person.find(:all:offset => 10, :limit => 10)
  8. Person.find(:all:include => [ :account:friends ])
  9. Person.find(:all:group => "category")
Find with lock
• Imagine two concurrent transactions: each will read person.visits == 2, add 1 to it, and save, resulting in two saves of person.visits = 3. By locking the row, the second transaction has to wait until the first is finished; we get the expected person.visits == 4.
  1. Person.transaction do
  2. person = Person.find(1, :lock => true)
  3. person.visits += 1
  4. person.save!
  5. end
Conditions
• Conditions can either be specified as a string, array, or hash representing the WHERE-part of an SQL statement.
条件能够被赋予字符串,数组,或者hash
> The array form is to be used when the condition input is tainted and requires sanitization.
> The string form can be used for statements that don‘t involve tainted data.
> The hash form works much like the array form, except only equality and range is possible. Examples:
Examples: Conditions
• Array form
> User.find(:all, :conditions=>["hobby=? AND name=?", 'swimming', 'Tom']
• String form
> User.find(:all, :conditions=>"hobby='swimming'", :order=>"hobby DESC, age")
• Hash form
> User.find(:all, :conditions=>{:hobby=>'swimming', :name=>'Tom'}, :order=>"hobby DESC, age")

Dynamic Attributebased Finders
Dynamic Attribute-based Finders
• Dynamic attribute-based finders are a cleaner way of getting (and/or creating) objects by simple queries without turning to SQL.
• They work by appending the name of an attribute to find_by_ or find_all_by_, so you get finders like
Person.find_by_user_name, Person.find_all_by_last_name, and Payment.find_by_transaction_id.

Dynamic Find Operation
• So instead of writing Person.find(:first, :conditions => ["user_name = ?", user_name]), you just do Person.find_by_user_name(user_name).
• And instead of writing Person.find(:all, :conditions => ["last_name = ?", last_name]), you just do Person.find_all_by_last_name(last_name).


ActiveRecord Validation
ActiveRecord::Validations
• Validation methods
  1. class User < ActiveRecord::Base
  2. validates_presence_of :username:level
  3. validates_uniqueness_of :username
  4. validates_oak_id :username
  5. validates_length_of :username:maximum => 3, :allow_nil
  6. validates_numericality_of :value:on => :create
  7. end
Validation


ActiveRecord::Validations
• Active Records implement validation by overwriting Base#validate (or the variations, validate_on_create and validate_on_update).
Active Records实现了验证通过重写Base#validate
  1. class Person < ActiveRecord::Base
  2. protected
  3. def validate
  4. errors.add_on_empty %w( first_name last_name )
  5. errors.add("phone_number""has invalid format"unless phone_number =~ /[0-9]*/
  6. end
  7. def validate_on_create # is only run the first time a new object is saved
  8. unless valid_discount?(membership_discount)
  9. errors.add("membership_discount""has expired")
  10. end
  11. end
  12. end

ActiveRecord Migration
ActiveRecord Migration
• Manage the evolution of a schema used
 > It’s a solution to the common problem of adding a field to make a new feature work in your local database, but being unsure of how to push that change to other developers and to the production server.
这是个解决添加成员在本地数据库的方法
• You can describe the transformations in self-contained classes that can be checked into version control systems and executed against another database that might be one, two, or five versions behind.

Example: Migration
• Add a boolean flag to the accounts table and remove it again, if you’re backing out of the migration.
  1. class AddSsl < ActiveRecord::Migration
  2. def self.up
  3. add_column :accounts:ssl_enabled:boolean:default => 1
  4. end
  5. def self.down
  6. remove_column :accounts:ssl_enabled
  7. end
  8. end

Example: Migration
• First adds the system_settings table, then creates the very first row in it using the Active Record model that relies on the table.
  1. class AddSystemSettings < ActiveRecord::Migration
  2. def self.up
  3. create_table :system_settings do |t|
  4. t.column :name:string
  5. t.column :label:string
  6. t.column :value:text
  7. end
  8. SystemSetting.create :name => "notice":label => "Use notice?":value => 1
  9. end
  10. def self.down
  11. drop_table :system_settings
  12. end
  13. end
Available Transformations
• create_table(name, options)
• drop_table(name)
• rename_table(old_name, new_name)
• add_column(table_name, column_name, type, options)
• rename_column(table_name, column_name, new_column_name)
• change_column(table_name, column_name, type, options)
• remove_column(table_name, column_name)
• add_index(table_name, column_names, index_type, index_name)
• remove_index(table_name, index_name)

Callbacks
回滚
What is Callback?
• Callbacks are hooks into the lifecycle of an Active Record object that allow you to trigger logic before or after an alteration of the object state.
回滚就是一个生命周期的一个点,可以在发生改变后混滚到该点
• This can be used to make sure that associated and dependent objects are deleted when destroy is called (by overwriting before_destroy) or to massage attributes before they‘re validated (by overwriting before_validation).

Lifecycle of an ActiveRecord Object
• (-) save
• (-) valid
• (1) before_validation
• (2) before_validation_on_create
• (-) validate
• (-) validate_on_create
• (3) after_validation
• (4) after_validation_on_create
• (5) before_save
• (6) before_create
• (-) create
• (7) after_create
• (8) after_save

Example: Callbacks in a Model
• The callback before_validation_on_create gets called on create.
  1. class User < ActiveRecord::Base
  2. # Strip everything but alphabets
  3. def before_validation_on_create
  4. self.name = name.gsub(/[^A-Za-z]/, ""if attribute_present?("name")
  5. end
  6. # More code
  7. end

Exception Handling
异常处理
Exception Handling
• Handle RecordNotFound Exception
  1. begin
  2. User.find(2345)
  3. rescue ActiveRecord::RecordNotFound
  4. outs “Not found!”
  5. end


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
东南亚位于我国倡导推进的“一带一路”海陆交汇地带,作为当今全球发展最为迅速的地区之一,近年来区域内生产总值实现了显著且稳定的增长。根据东盟主要经济体公布的最新数据,印度尼西亚2023年国内生产总值(GDP)增长5.05%;越南2023年经济增长5.05%;马来西亚2023年经济增速为3.7%;泰国2023年经济增长1.9%;新加坡2023年经济增长1.1%;柬埔寨2023年经济增速预计为5.6%。 东盟国家在“一带一路”沿线国家中的总体GDP经济规模、贸易总额与国外直接投资均为最大,因此有着举足轻重的地位和作用。当前,东盟与中国已互相成为双方最大的交易伙伴。中国-东盟贸易总额已从2013年的443亿元增长至 2023年合计超逾6.4万亿元,占中国外贸总值的15.4%。在过去20余年中,东盟国家不断在全球多变的格局里面临挑战并寻求机遇。2023东盟国家主要经济体受到国内消费、国外投资、货币政策、旅游业复苏、和大宗商品出口价企稳等方面的提振,经济显现出稳步增长态势和强韧性的潜能。 本调研报告旨在深度挖掘东南亚市场的增长潜力与发展机会,分析东南亚市场竞争态势、销售模式、客户偏好、整体市场营商环境,为国内企业出海开展业务提供客观参考意见。 本文核心内容: 市场空间:全球行业市场空间、东南亚市场发展空间。 竞争态势:全球份额,东南亚市场企业份额。 销售模式:东南亚市场销售模式、本地代理商 客户情况:东南亚本地客户及偏好分析 营商环境:东南亚营商环境分析 本文纳入的企业包括国外及印尼本土企业,以及相关上下游企业等,部分名单 QYResearch是全球知名的大型咨询公司,行业涵盖各高科技行业产业链细分市场,横跨如半导体产业链(半导体设备及零部件、半导体材料、集成电路、制造、封测、分立器件、传感器、光电器件)、光伏产业链(设备、硅料/硅片、电池片、组件、辅料支架、逆变器、电站终端)、新能源汽车产业链(动力电池及材料、电驱电控、汽车半导体/电子、整车、充电桩)、通信产业链(通信系统设备、终端设备、电子元器件、射频前端、光模块、4G/5G/6G、宽带、IoT、数字经济、AI)、先进材料产业链(金属材料、高分子材料、陶瓷材料、纳米材料等)、机械制造产业链(数控机床、工程机械、电气机械、3C自动化、工业机器人、激光、工控、无人机)、食品药品、医疗器械、农业等。邮箱:market@qyresearch.com

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值