ActiveRecord 일대다, 다대다 표현

완벽한 RoR 공부 메모입니다.
Active Record 주위의 정리. 어떤 SQL이 흐르는지 항상 의식하고 싶다.

모델



일대다 관계



예) User(1)는 복수의 Ticket(다)을 가진다



class User << ActiveRecord::Base
  has_many :tickets
...

end


class Ticket << ActiveRecord::Base
  belongs_to :user
...

end


상기의 설정을 넣는 것으로, Ticket 모델의 user_id가 외래 키이고, User 모델의 id가 참조 키이면, Active Record가 해석해 준다.

irb(main):007:0> user = User.find(1)
  User Load (0.7ms)  SELECT  `users`.* FROM `users`  WHERE `users`.`id` = 1 LIMIT 1

#user(id=1)の持つ全チケットを表示
#where句でuser_id = 1が条件に入る   
irb(main):008:0> user.tickets
  Ticket Load (1.3ms)  SELECT `tickets`.* FROM `tickets`  WHERE `tickets`.`user_id` = 1



irb(main):023:0* ticket = Ticket.find(4)
  Ticket Load (0.4ms)  SELECT  `tickets`.* FROM `tickets`  WHERE `tickets`.`id` = 4 LIMIT 1

#ticket(id=4)を所有するユーザ(1つ)を表示
#where句でuser.id = ticket.user_id(1)が入る
irb(main):024:0> ticket.user
  User Load (0.7ms)  SELECT  `users`.* FROM `users`  WHERE `users`.`id` = 1 LIMIT 1


다 대다 관계



User(1)는 복수의 Event에 참가하고 있다.
Event(1)에는 복수의 User가 참가한다.



이것을, 예를 들면 events에 user_id, users에 event_id를 갖게 한 경우, 같은 User가, 다른 event_id로 복수 존재하는 등의 문제가 일어난다.

해결 방법으로서 중간 모델(Ticket)로 표현을 한다.


class User < ActiveRecord::Base
 has_many :tickets
 has_many :events, through: :tickets #EventとTicketをevent_idで内部結合し、ticket.user_id=ユーザIDで絞りこみしてEventへアクセス
...

end
class Event < ActiveRecord::Base
  has_many :tickets
  has_many :users, through: :tickets #UserとTicketをuser_idで内部結合し、ticket.event=id=イヴベントIDで絞り込みしてUserへアクセス
...

end

class Ticket < ActiveRecord::Base
  belongs_to :user
  belongs_to :event
...

end
irb(main):001:0> u = User.find(1)
  User Load (0.3ms)  SELECT  `users`.* FROM `users`  WHERE `users`.`id` = 1 LIMIT 1
irb(main):002:0> u.events
  Event Load (0.5ms)  SELECT `events`.* FROM `events` INNER JOIN `tickets` ON `events`.`id` = `tickets`.`event_id` WHERE `tickets`.`user_id` = 1

irb(main):007:0* event=Event.find(1)
  Event Load (1.1ms)  SELECT  `events`.* FROM `events`  WHERE `events`.`id` = 1 LIMIT 1
irb(main):008:0> event.users
 User Load (0.4ms)  SELECT `users`.* FROM `users` INNER JOIN `tickets` ON `users`.`id` = `tickets`.`user_id` WHERE `tickets`.`event_id` = 1

좋은 웹페이지 즐겨찾기