[英]Understanding Relational with ActiveRecord in Rails
我理解SQL我理解数据库方法我理解Rails我不懂ActiveRecord关系
我有三个模型(简化),我用rails g模型创建,然后执行rake db:使用mysql db进行迁移。
Calendar
id: number
name: string
Event
id: number
title: string
Event_Tag
id: number
event_id
key: string
value: string
我如何对所有事件执行查询并检索每个事件的所有event_tags,以便我可以用最少的查询构建JSON模型?
Event
id: number
title: string
tags: [
<key>:<value>,
<key>:<value>,
<key>:<value>,
]
我试过这个:
events = Event.includes(:event_tag).where("events.calendar_id" => params[:calendar_id])
我所见,避免了N + 1查询问题。 它执行2个查询。
Event Load (47.1ms) SELECT `events`.* FROM `events` WHERE `events`.`calendar_id` = 1
EventTag Load (46.3ms) SELECT `event_tags`.* FROM `event_tags` WHERE `event_tags`.`event_id` IN (1)
但是,当我检查一个事件
eventHash = events[0]
我收到
#<ActiveRecord::Relation [#<Event id: 1, title: "Test", calendar_id: 1, created_at: nil, updated_at: nil>]>
ActiveRecord的
虽然我不知道ActiveRecord的幕后工作,但我知道这就是所谓的ORM(对象相关映射)系统 (SQL框架)
这意味着它为您提供了一系列调用方法,然后将其转换为相关的SQL查询( joins
等)
协会
ActiveRecord关联基本上是美化的join
语句 - 每次调用一个对象,然后引用它的关联数据,你基本上会调用两个查询来ping两个单独的数据表。
AR的工作方式是使用foreign_key
#app/models/event.rb
Class Event < ActiveRecord::Base
has_many :tags, class_name: "EventTag"
end
#app/models/event_tag.rb
Class EventTag < ActiveRecord::Base
belongs_to :event
end
这将允许您调用以下内容:
@event = Event.find params[:id]
@event.tags.each do |tag|
tag.name
tag.value
end
如果这有帮助,如果你发表评论,我会看到有关帮助将tags
组合成JSON哈希的方法,虽然我不确定你要用的是什么
Rails eager中的includes
方法将关系加载到内存中以便更快地访问,因此应用程序不会执行所有N + 1查询。
因此,即使在检查代码时没有显示关系,如果通过关系(例如event.event_tag.key
)访问它,应用程序也不会执行其他查询,因为数据已经存在于内存中。
这是一篇非常好的文章,解释了Rails中的热切加载(讨论includes
和其他有用的方法eager_load
和preload
以及它们如何相关): http : eager_load
至于构建JSON对象,它实际上取决于你如何处理它。 我想最常见的库(例如jbuilder或active_model_serializers)会处理关系查询。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.