设已经有一个model User,他继承自ActiveRecord
user = User.create(attributes) 创建一个用户
user.destroy() 删除
User.find(id)
User.find_by(conditions)
User.all() 返回全部
User.first
User.last
//update
user.name = "..."
user,save(validate:true)//
//or
user.update_attributes(attributes)
update_attribtues会验证模型的有效性,而update_attribute不会
relation
一对一:
User有一个Profile,因此是一个一对一的关系,
在User中定义has_one :profile
在Profile中定义belongs_to :user
在Profile的migrate文件中加入user_id:integer即可。
user = User.first
user.profile = a_new_profile
user.save
就ok了
最方便的情况是user.create_profile//该方法rails会为我们自动创建
一对多:
user有多个文章,自然在Article中需要定义belong_to :user,在user里定义has_many :articles
比较神奇的是,当调用user.articles << article时,save操作会被自动调用
多对多
一个article属于多个Category,一个Category也有多个article,
1.rake g migration create_articles_categories
2.在生成的文件中加上来去除默认的id
create_table :articles_categories, id: false do
3.定义reference,两种风格可供选择
t.references :category, t.references :article ,
当然也可以使用 t.integer :category_id, t.integer :article_id
4.最后在类中加入has_many_and_belongs_to ...
29.ActiveRecord对象的errors可以追加自定义错误
@users.errors.add(:custom_error,"error")
30.可以给created_time加上order,比如在MicroPost里,定义如下语句,即可按照创建顺序倒序排列
default_scope -> { order(created_at: :desc) }
31.created_at属性在对象create的时候会被rails用最新的时间覆盖,但是在fixture测试时可以自己指定
32.time_ago_in_words 函数用于把过去的时间表现的人性化
37.Rails transaction和script
可以将脚本放在script文件夹中,这里的脚本可以引用到当前Rails项目的类
如下面的脚本向系统导入100个订单
rails runner script/load_orders.rb
ActiveRecord::Base.transaction do #Rails 事务(1..100).each do |i| Order.create(name: "Customer #{i}", address: "#{i} Main Street", email: "customer-#{i}@example.com", pay_type: "Check") endend
38.
ActiveRecord::Base.where接受如下参数类型
where("a=#{qq}"),这样容易受到sql injection攻击
where(a:1,b:2)
或者
where("a <= ? and b> ?",1,2)
或者
where("a < :a? and b > :b",a:1,b:2)
where语句是一个执行计划,不会调用sql语句,
在他后方还可以加入其他计划,如offset,limit,order
加.to_sql可以查看sql语句
要执行的话,
需要在他后面加上例如.all,.each,.map。
最后加上.select("field1,field2")可以截取出需要的属性
加上.readonly返回的元素不能再次调用save方法
39.
ActiveModel::Base
update(id,attributes_hash) //获取一个对象并用新属性更新它
Book.where('title LIKE ?', '%Rails%').update_all(author: 'David') //更新多个对象
Book.all和Book.where返回的是Book::ActiveRecord_Relation类型,可以使用update_all操作。
而Book.find([1,2,3])返回的是一个Book类型的Array
//Delete
Order.delete(123)
User.delete([2,3,4,5])
40.为model加上回调方法
所有的before_方法返回false将阻止后续操作的发生,但是返回nil不影响
该文件建议和model放在一个文件夹下,
class TitleEncrypter def before_save(product) product.title.tr!("a-z", "b-za") end def after_save(product) product.title.tr!("b-za", "a-z") end alias_method :after_find, :after_save end class ActiveRecord::Base def self.encrypt encrypt = TitleEncrypter.new before_save encrypt after_save encrypt after_find encrypt end end
在Product.model中只需要即可
class Product < ActiveRecord::Base
encrypt
end
41.加入一个新的scope
scope :recent_registered, -> { where("created_at > ?", 1.week.ago) }然后可以通过User.recent_registered来调用