rails on ruby,ruby on rails 之 Active Record

Active Record是Rails提供的对象关系映射(Object-Relational Mapping,ORM)层,是 Rails 中负责实现应用模型的部分。
一个 ApplicationRecord 子类(例如我们定义的 Order 类)对应一个数据库表。默认情况下,Rails假定模型类对应的表名使用类名的复数形式。如果类名包含多个首字母大写的单词,则表名使用下划线分隔单词。下面提供几个简单说的例子:

类名和表名的对应关系

类名          表名
Order        orders
TaxAgency    tax_agencies
Batch        batchs
LineItem     line_items

现在有一种特殊情况,假如我们数据库底层的表并不是用rails框架创建的。比如说,我现在底层有一张表,叫actived_info。很明显,这虽然是驼峰式的命名,但是确实单数的,所以我们需要显式地指定表名。

class ActivedInfoAws < BaseAws
  self.table_name = 'actived_info'
end

在模型中指定关系
Active Record 支持在表之间建立三种关系:一对一、一对多和多对多。这些关系分别使用模型中的声明表 示:has_one、has_many、belongs_to,以及巧妙命名的 has_and_belongs_to_many。

一对一关系
一对一关系(或更准确地说,一对零或一对一关系)的实现方式是,在一个表中的一行里使用外键引用另一 个表中的一行,而且最多引用一行。订单和发票之间存在一对一关系,因为一个订单最多有一个发票。

在 Rails 中声明这个一对一关系的方式是,在 Order 模型中添加 has_one 声明,并在 In- voice 模型中添加 belongs_to 声明。
这个示例说明了一个重要规则:belongs_to 声明始终放在外键所在表对应的模型中。而且在UML图中,我们的箭头是由belongs指向has_one。

一对多关系
一对多关系用于表述对象集合。例如,一个订单中可以有任意多个商品。在数据库中,一个订单中的每个商品记录都具有引用该订单的外键列。

在 Active Record 中,父对象(逻辑上包含一系列子对象的对象)使用 has_many 声明与子对象之间的关系, 而子对象使用belongs_to指明父对象。在这个示例中,子对象LineItem belongs_to :order,,而父对象Order has_many :line_items。

再强调一次,因为外键在商品记录中,所以 belongs_to 声明放在对应的 LineItem 模型中。

class AddManagerIdToRoles < ActiveRecord::Migration
  def change
    change_table :roles do |t|
      t.integer :manager_id
    end
  end
end

class Role < ActiveRecord::Base
  belongs_to :manager, class_name: "Admin"
end

def manager_email
    manager&.email
end

def manager_email=(val)
    self.manager = Admin.find_by(email: val)
end

在这里,Role的外键是manager_id, 但是这里的一对多的模型,并没有用has_many声明关系。

多对多关系
最后,产品可以分类,一个产品可以属于多个分类,而一个分类中可以包含多个产品,这就是多对多关系。这就好像关系的两端都包含另一端的多个对象。

在 Rails 中声明多对多关系的方式是,在两个模型中都添加 has_and_belongs_to_many 声明。 多对多关系是对称的,两个表都使用 has_and_belongs_to_many 表示相互关联。

class Questionnaire < ApplicationRecord
  has_and_belongs_to_many :questions
end

class Question < ApplicationRecord
  has_and_belongs_to_many :questionnaires
end

questionnaire.questions << Question.where(description: params[:questionnaire][:question_ids])

Rails 通过中间联结表(join table)实现多对多关联,这个表中包含指向两个目标表的外键。Active Record 假定联结表的名称是由两个目标表的名称按字母表顺序拼接而来。假如说两个目标表是categories 表和 products 表,所以 Active Record 会查找名为 categories_products 的联结表。联结表也可以由我们自己直接定义,用through关键字:

class UserInfo < ActiveRecord::Base
  validates :uid, presence: true
  has_many :user_device_associations
  has_many :device_infos, through: :user_device_associations
end

class DeviceInfo < ActiveRecord::Base
  validates :device_id, :sn, presence: true
  has_many :user_device_associations
  has_many :user_infos, through: :user_device_associations
end

class UserDeviceAssociation < ActiveRecord::Base
  belongs_to :device_info
  belongs_to :user_info
end

这里是利用user_device_associations作为联结表,一个用户可能名下可能有多个设备信息,而一个设备信息可能绑定多个用户。

class CreateUserDeviceAssociations < ActiveRecord::Migration
  def change
    create_table :user_device_associations, options: 'ROW_FORMAT=DYNAMIC DEFAULT CHARSET=utf8' do |t|
      t.belongs_to :device_info, index: true
      t.belongs_to :user_info, index: true
      t.boolean :isbook, default: true
      t.string  :product_type
      t.index [:device_info_id, :user_info_id], unique: true, name: :index_of_device_and_user

      t.timestamps null: false
    end
  end
end

在这里,我们可以利用联结表储存product_type的信息,并将两个外键声明为唯一索引,唯一索引是不能重复的。

includes和joins的区别与用法

https://blog.csdn.net/sxs_smile/article/details/71312268

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值