惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
Jina AI
Jina AI
Forbes - Security
Forbes - Security
雷峰网
雷峰网
人人都是产品经理
人人都是产品经理
博客园 - 叶小钗
V
Visual Studio Blog
月光博客
月光博客
博客园 - Franky
有赞技术团队
有赞技术团队
宝玉的分享
宝玉的分享
博客园 - 三生石上(FineUI控件)
酷 壳 – CoolShell
酷 壳 – CoolShell
Apple Machine Learning Research
Apple Machine Learning Research
The Register - Security
The Register - Security
S
SegmentFault 最新的问题
博客园 - 司徒正美
P
Proofpoint News Feed
Know Your Adversary
Know Your Adversary
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
A
Arctic Wolf
Cyberwarzone
Cyberwarzone
Simon Willison's Weblog
Simon Willison's Weblog
U
Unit 42
P
Proofpoint News Feed
Scott Helme
Scott Helme
MyScale Blog
MyScale Blog
T
Tenable Blog
Hugging Face - Blog
Hugging Face - Blog
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
小众软件
小众软件
C
CERT Recently Published Vulnerability Notes
P
Palo Alto Networks Blog
V
V2EX
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
T
Tailwind CSS Blog
V
Vulnerabilities – Threatpost
Latest news
Latest news
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
I
Intezer
Microsoft Azure Blog
Microsoft Azure Blog
爱范儿
爱范儿
博客园 - 【当耐特】
B
Blog RSS Feed
N
Netflix TechBlog - Medium
Recent Announcements
Recent Announcements
NISL@THU
NISL@THU
C
Cisco Blogs
C
CXSECURITY Database RSS Feed - CXSecurity.com
S
Schneier on Security

博客园 - kevinhgy

什么是REST架构 Ruby on Rails中执行存储过程和指定SQL语句的方法 Ruby on Rails 性能优化的 10 大建议 向Google、Yahoo!、MSN、Ask和百度提交网站地图Sitemap总结 寻找Ruby on Rails项目兼职开发人员 rails 收藏 RoR中的一些基础知识[转载收藏] - kevinhgy - 博客园 Ruby: Active Controller(转载收藏) Perl Oicq 代码 [目录索引]──chenpeng兄发布 Msn Messager用户签名指令参考 MSN Protocol Version 11 简单介绍一下这个机器人(转载) - kevinhgy - 博客园 .NET(C#)连接各类数据库-集锦 (转载) - kevinhgy - 博客园 MMS 协议概述 编写自己的MSN机器人[转载] 惠普最新招聘 招募赴日IT/SAP SE/SSE/TL/PM,欢迎大家咨询. [外资银行]诚聘人才 Linux date 用法
Ruby: ActiveRecord Realation(转载收藏)
kevinhgy · 2008-03-05 · via 博客园 - kevinhgy

ActiveRecord Realation

convention 约定

对应关系:

  • 普通对象: Person -> people table -> person_id
  • join_table: tablenamea_tablenameb 为table名(按照字母顺序排列)

关系

注意belongs_to对应的表必须有外键, rails认为一个表belongs_to他外键引用的表

  • one-to-one

    class Order < ActiveRecord::Base
        has_one :invoices
        . . .
        class Invoice < ActiveRecord::Base
        belongs_to :order
        . . .
        
  • one-to-many: belongs_to

    class Order < ActiveRecord::Base
        has_many :line_items
        . . .
        class LineItem < ActiveRecord::Base
        belongs_to :order
        . . .
        
  • many-to-many

    class Product < ActiveRecord::Base
        has_and_belongs_to_many :categories
        . . .
        class Category < ActiveRecord::Base
        has_and_belongs_to_many :products
        . . .
        

one-to-one

下面两个操作在逻辑在等价

  • order.invoce=invo
  • auto invo.save

注意1

当把子对象赋给父的时候(order.invoce=invo),子对象如果未存储会自动存储(auto invo.save),但是把父赋给子的时候(invo.order=ord)不会自动存储, 因为此时存储order没有意义, 对应关系是保存在invoces表中的,不过在稍后的invo.save中, 如果父没有创建,还是会自动创建的

注意2 当使用上门的自动存储的时候,由于调用的save方法,所以即使出错也不会报告,所以最好还是自己来invo.save!(比如invo有内部验证的时候),然后在建立连接关系

belongs_to扩展参数,如下例子

class LineItem < ActiveRecord::Base
belongs_to :paid_order,
:class_name => "Order",
:foreign_key => "order_id",
:conditions => "paid_on is not null"
end
  • :class_name :对应的类
  • :foreign_key :指定外键名
  • :conditions : 用来筛选外键表中的记录(此时foreign_key不能唯一确定记录,或者有不需要的记录)

has_one 也有类似的功能, 多了两个

  • :denpendent

    删除父亲的时候自动删除孤儿(参见hibernate) ???实现失败,加上不加上都不会删除,数据库报外键约束错误

  • :order

    排序,虽然是has_one, 但是这个one可以通过排序动态得到(比如最高分的选手)

hash_one and belongs_to 增加的方法

belongs_to和has_one都会给对象添加下面的方法,假设对应的是product对象

  • product(force_reload=false)

    Return the associated product (or nil if no associated product exists).The result is cached, and the database will not be queried again if this order had previously been fetched unless true is passed as a parameter.

  • product=(obj)

    Associate this line item with the given product, setting the foreign key in this line item to the product’s primary key. If the product has not been saved, it will be when the line item is saved, and the keys will be linked at that time.

  • build_product(attributes={})

    Construct a new product object, initialized using the given attributes.This line item will be linked to it. The product will not yet have been saved.

  • create_product(attributes={})

    Build a new product object, link this line item to it, and save the product.

one-to-many

has_many 扩展声明(未列出的与has_one相同)

  • :dependent

    会把关联他的对象一个一个load出来调用它们的destory

  • :exclusively_dependent

    一个sql删除:denpent需要删除的对象,但是需要保证这些对象真是孤儿而且没有callback

  • :finder_sql

    构建动态的子对象群

  • :counter_sql

    finder_sql调用前call他得到数量, 如果不给出,会自动通过finder_sql添加"count(*)"来计算

  • :order

    排序

has_many 增加的方法

  • orders(force_reload=false)

    Returns an array of orders associated with this customer (which may be empty if there are none). The result is cached, and the database will not be queried again if orders had previously been fetched unless true is passed as a parameter.

  • orders <

    Adds order to the list of orders associated with this customer.orders.push(order1, ...) Adds one or more order objects to the list of orders associated with this customer. concat( ) is an alias for this method.

  • orders.delete(order1, ...)

    Deletes one or more order objects from the list of orders associated with this customer. This does not delete the order objects from the database—it simply sets their customer_id foreign keys to null, breaking their association.

  • orders.clear

    Disassociates all orders from this customer. Like delete( ), this breaks the association but deletes the orders from the database only if they were marked as :dependent.

  • orders.find(options...)

    Issues a regular find( ) call, but the results are constrained only to return orders associated with this customer. Works with the id, the :all, and the :first forms.

  • orders.build(attributes={})

    Constructs a new order object, initialized using the given attributes and linked to the customer. It is not saved.

  • orders.create(attributes={})

    Constructs and save a new order object, initialized using the given attributes and linked to the customer.

many-to-many

在many-to-many中,必须有一个jiontable, 用来保存对应关系,表名的规则是按照字母顺序连接,如 table categories_products join table不能有id ,一方面不需要, 另外一方面会在自动include中覆盖父对象的id

join table额外保存的属性,按道理不应该额外保存属性,额外的属性越明显,就越说明此处的many-to-many关系设计得有问题,适当时候要抽象出一个新model来分别belongs_to两个父亲

relation 中的延迟读取

默认relation关系中都是延迟读取的,如果需要一次性遍历多个记录操作, 可以采用:include指令,下面例子中,include读取三个表只需要一个sql语句(采用left join,需要数据库支持) for post in Post.find(:all, :include => [:author, :comments]) puts "Post: #{post.title}" puts "Written by: #{post.author.name}" puts "Last comment on: #{post.comments.first.created_on}" end

同时要注意,有:include和:condition一起的时候,字段名要全名,如下 ost.find(:all, :conditions => "posts.title like '%ruby%'", :include => [:author, :comments]) # ...

counter_cache

belongs_to :xxx,:counter_cache=>true ,同时父对象表中需要如下的新字段 line_items_count int default 0,注意默认值必须为0(或者其他机制保证初始化为0),否则每次都是null 可以避免每次count都去数据库count(*),这里的cache会在数据增删的时候自动维护

注意 以上的自动更新时, 直接给儿子们更新父亲时是不起作用的, 必须使用father.children(:refresh)才能更新但是使用father.children<< child就没有问题 ???