[英]Understanding Relational with ActiveRecord in Rails
I understand SQL I understand Database Methodology I understand Rails I don't understand ActiveRecord Relations 我理解SQL我理解数据库方法我理解Rails我不懂ActiveRecord关系
I have three models (simplified) that i created with rails g model and then performed a rake db:migrate with a mysql db. 我有三个模型(简化),我用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
How would i perform a query for all events and retrieve all the event_tags for each so that i could build a JSON model with minimal queries? 我如何对所有事件执行查询并检索每个事件的所有event_tags,以便我可以用最少的查询构建JSON模型?
Event
id: number
title: string
tags: [
<key>:<value>,
<key>:<value>,
<key>:<value>,
]
I have tried this: 我试过这个:
events = Event.includes(:event_tag).where("events.calendar_id" => params[:calendar_id])
Which i have seen avoids the N+1 query issue. 我所见,避免了N + 1查询问题。 And it performs 2 queries. 它执行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)
But when i inspect an event 但是,当我检查一个事件
eventHash = events[0]
i receive 我收到
#<ActiveRecord::Relation [#<Event id: 1, title: "Test", calendar_id: 1, created_at: nil, updated_at: nil>]>
ActiveRecord ActiveRecord的
Although I don't know the behind-the-scenes workings of ActiveRecord, I do know it's what's called an ORM (Object Related Mapping) system (framework for SQL) 虽然我不知道ActiveRecord的幕后工作,但我知道这就是所谓的ORM(对象相关映射)系统 (SQL框架)
This means it gives you a series of methods to call, which it will then translate into the relevant SQL queries ( joins
etc) 这意味着它为您提供了一系列调用方法,然后将其转换为相关的SQL查询( joins
等)
Associations 协会
ActiveRecord associations are basically glorified join
statements - each time you call an object, and then reference its associated data, you will basically be calling two queries to ping two separate data tables. ActiveRecord关联基本上是美化的join
语句 - 每次调用一个对象,然后引用它的关联数据,你基本上会调用两个查询来ping两个单独的数据表。
The way AR works is to use the foreign_key
AR的工作方式是使用foreign_key
I think your problem is best solved using an association defined in your Event
model: 我认为使用Event
模型中定义的关联可以最好地解决问题:
#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
This will allow you to call the following: 这将允许您调用以下内容:
@event = Event.find params[:id]
@event.tags.each do |tag|
tag.name
tag.value
end
If this helps, if you comment, I'll see about helping combine the tags
into a JSON hash for you, although I'm not sure what you're trying to do with that exactly 如果这有帮助,如果你发表评论,我会看到有关帮助将tags
组合成JSON哈希的方法,虽然我不确定你要用的是什么
The includes
method in Rails eager loads the relationships into memory for quicker access so the application doesn't do all the N+1 queries. Rails eager中的includes
方法将关系加载到内存中以便更快地访问,因此应用程序不会执行所有N + 1查询。
So even though the relation doesn't show up when you inspect the code, if you access it thru the relation (eg event.event_tag.key
) the application doesn't perform additional queries since the data is already present in memory. 因此,即使在检查代码时没有显示关系,如果通过关系(例如event.event_tag.key
)访问它,应用程序也不会执行其他查询,因为数据已经存在于内存中。
Here's a really good article explaining eager loading in Rails (discusses includes
and other useful methods eager_load
and preload
and how they're all related): http://blog.arkency.com/2013/12/rails4-preloading/ 这是一篇非常好的文章,解释了Rails中的热切加载(讨论includes
和其他有用的方法eager_load
和preload
以及它们如何相关): http : eager_load
As far as building the JSON object, it really depends on how you're going about that. 至于构建JSON对象,它实际上取决于你如何处理它。 I'd imagine the most common libraries (eg jbuilder or active_model_serializers) would handle the relations query fine. 我想最常见的库(例如jbuilder或active_model_serializers)会处理关系查询。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.