2009-11-28 3 views
1

Мое понимание отношений has_many в Rails заключается в том, что он будет использовать JOIN для поиска связанных строк. Если бы я реализовал это с нуля, я бы создал реляционную таблицу. Правильно ли я полагаю, что будет медленнее использовать JOIN? В Django я считаю, что реляционные таблицы созданы, и я знаю, что я могу использовать реляционную таблицу в Rails, если захочу. Мне интересно, почему это поведение по умолчанию, и если оно вообще имеет значение.has_many in Rails использует JOIN

Благодаря

ответ

2

Нет, по умолчанию has_many Отношения не используйте соединение, чтобы найти связанные строки. Вот быстрые сеансы командной строки, которые показывают это (у меня включен отладочный журнал для моего скрипта/консоли).

$ rails has_many_test 

$ cd has_many_test 

$ ruby script/generate model account 

$ ruby script/generate model user account_id:integer 

$ rake db:migrate 

$ ruby script/console 
Loading development environment (Rails 2.3.4) 
>> Account.has_many :users 
>> a = Account.create 
    Account Create (0.4ms) INSERT INTO "accounts" ("created_at", "updated_at") VALUES('2009-11-28 18:06:50', '2009-11-28 18:06:50') 
>> a.users 
    User Load (0.3ms) SELECT * FROM "users" WHERE ("users".account_id = 1) 

Однако, если has_many отношение определяет :through или :include вариантов, то SQL приведет в JOIN, но правильно так.

1

Rails не будет использовать какие-либо присоединяется, если вы не сказать ему, чтобы сделать это.

не Допустим, у вас есть User модель с has_many :posts:

User.all 
# SELECT * FROM `users` 

User.all :joins => :posts 
# SELECT `users`.* FROM `users` INNER JOIN `posts` ON posts.user_id = users.id 

User.all :include => :posts 
# SELECT * FROM `users` 
# SELECT `posts`.* FROM `posts` WHERE (`posts`.user_id IN (1,2)) 

Если вам не нужны/хотят присоединиться то будет не присоединиться.

1

В ActiveRecord (который является ORM, используемым по умолчанию в Rails, но не единственным возможным), отношения has_many обычно включают две модели и, следовательно, две таблицы. Таким образом, эти модели:

class Order < ActiveRecord::Base 
    has_many :order_items 
end 

class OrderItem < ActiveRecord::Base 
    belongs_to :order 
end 

... orders будет ссылаться и order_items таблицы, последний имеет foreign_key order_id ссылку на родительский заказ.

Order.find(some_id) 

будет получать один заказ. order_items не будет затронут, если вы не указали его явно, или не добавьте директивы в определение класса, чтобы требовать, чтобы ассоциация всегда была перемещена.

Я не уверен, почему вы так обеспокоены использованием объединений. При соответствующей индексации почти любая современная СУБД будет очень эффективной: это то, что они предназначены для работы.

+0

Спасибо. Я не очень беспокоюсь об этом. Просто любопытно. Я подумал, что это делает что-то, что имело смысл. Мне казалось, что это не так, как я научился делать это в школе. –