2012-09-07 2 views
1

기존 카드 모델에 대한 '타임 라인'기능을 만들고 싶습니다. 카드에는 이미 has_many 메모와 has_many 첨부 파일이 있습니다. 같은 좋은 방법으로 통합 컬렉션기존 has_many 모델을 나타내는 Rails 다형성 연관

  • 액세스 메모, 첨부 파일 (결국 다른 모델) : card.timeline
  • 여전히 카드에 액세스 할 수 나는 수 있도록하고 싶습니다 같은 노트와 첨부 파일 : card.notes
  • 은 여전히 ​​같은 메모의 상위 카드를 액세스 할 수 있습니다 : 카드 :
  • note.card 것은 API 등으로, 카드의 타임 라인에 항목을 추가 할 수 있습니다. 타임 라인 < <는 참고 내가 내 DB가 올바르게 설정되어 있다고 생각

, 그것은 내가 바로 얻을 수없는 것 협회의 선언입니다. 내 스키마는 다음과 같습니다.

create_table "cards", :force => true do |t| 
    t.string "name" 
    end 

    create_table "timeline_items", :force => true do |t| 
    t.integer "card_id", :null => false # FK from cards table 
    t.integer "item_id", :null => false # FK from notes or attachments table 
    t.string "item_type", :null => false # either 'Note' or 'Attachment' 
    end 

    create_table "notes", :force => true do |t| 
    t.text  "content" 
    end 

    create_table "attachments", :force => true do |t| 
    t.string "file_file_name" 
    end 

누구나 ActiveRecord를 사용하여이를 어떻게 달성 할 수 있는지 알고 있습니까? 정신이 바보 같아!

출발점입니다 : 좋아 미리 ~ 스투

답변

0

에서

class Card < ActiveRecord::Base 
    has_many :timeline_items 
    has_many :notes,  :through => :timeline_items, :source => :item, :source_type => 'Note', :order => 'updated_at DESC' 
    has_many :attachments, :through => :timeline_items, :source => :item, :source_type => 'Attachment', :order => 'updated_at DESC' 
end 

class TimelineItem < ActiveRecord::Base 
    belongs_to :card 
    belongs_to :item, :polymorphic => true 
end 

class Note < ActiveRecord::Base 
    has_one  :card, :through => :timeline_items 
    has_one  :timeline_item, :as => :item 
end 

감사합니다 -이과에 어려움을 겪고 후 오프, I에 유래을 게시 한 10 분 이내에 균열! 전형적인.

주 있었어야 :

class Note < ActiveRecord::Base 
    has_one  :card, :through => :timeline_item #not timeline_items 
    has_one  :timeline_item, :as => :item 
end 

을 그리고 그것은 그 것이었다

가 벽에 머리를 두드리는 다른 사람을 저장하려면, 여기에 내가 잘못했다거야! this article에 사용 된 생성 방법을 사용하려고했지만 실제로는 필요하지 않습니다.

1.9.2-p290 :009 > c = Card.find(547) 
    Card Load (0.3ms) SELECT `cards`.* FROM `cards` WHERE `cards`.`id` = 547 LIMIT 1 
=> #<Card id: 547, name: "Duplicates appearing"> 

1.9.2-p290 :010 > c.notes.count 
    (0.3ms) SELECT COUNT(*) FROM `notes` INNER JOIN `timeline_items` ON `notes`.`id` = `timeline_items`.`item_id` WHERE `timeline_items`.`card_id` = 547 AND `timeline_items`.`item_type` = 'Note' 
=> 4 

1.9.2-p290 :011 > c.notes.last.card 
    Note Load (2.7ms) SELECT `notes`.* FROM `notes` INNER JOIN `timeline_items` ON `notes`.`id` = `timeline_items`.`item_id` WHERE `timeline_items`.`card_id` = 547 AND `timeline_items`.`item_type` = 'Note' ORDER BY updated_at ASC LIMIT 1 
    Card Load (3.2ms) SELECT `cards`.* FROM `cards` INNER JOIN `timeline_items` ON `cards`.`id` = `timeline_items`.`card_id` WHERE `timeline_items`.`item_id` = 620 AND `timeline_items`.`item_type` = 'Note' LIMIT 1 
=> #<Card id: 547, name: "Duplicates appearing"> 

1.9.2-p290 :013 > c.notes << Note.new(:content => 'Holee Sheeet Dawg', :user_id => 1) 
    (0.2ms) BEGIN 
    SQL (0.6ms) INSERT INTO `notes` (`content`, `created_at`, `updated_at`, `user_id`) VALUES ('Holee Sheeet Dawg', '2012-09-07 11:38:55', '2012-09-07 11:38:55', 1) 
    (0.1ms) COMMIT 
    (0.1ms) BEGIN 
    SQL (0.3ms) INSERT INTO `timeline_items` (`card_id`, `created_at`, `item_id`, `item_type`, `updated_at`) VALUES (547, '2012-09-07 11:38:55', 625, 'Note', '2012-09-07 11:38:55') 
    (0.5ms) COMMIT 
    Note Load (1.8ms) SELECT `notes`.* FROM `notes` INNER JOIN `timeline_items` ON `notes`.`id` = `timeline_items`.`item_id` WHERE `timeline_items`.`card_id` = 547 AND `timeline_items`.`item_type` = 'Note' ORDER BY updated_at DESC 
=> [#<Note id: 625, content: "Holee Sheeet Dawg", user_id: 1, created_at: "2012-09-07 11:38:55", updated_at: "2012-09-07 11:38:55">, .....] 

1.9.2-p290 :014 > c.notes.count 
    (0.7ms) SELECT COUNT(*) FROM `notes` INNER JOIN `timeline_items` ON `notes`.`id` = `timeline_items`.`item_id` WHERE `timeline_items`.`card_id` = 547 AND `timeline_items`.`item_type` = 'Note' 
=> 5 

편집 : 여기

는 SQL 문이 모든 timeline_items 테이블을 사용하고 있는지 보여주는, 콘솔 출력의

난 그냥 눈치 card.timeline을 가진 내 요구 사항을 얻지 못한 그 아직 만났어. 여러 테이블에서 조인이 이루어지기 때문에 AR이 나를 위해 조인을 처리하지 못했습니다 (이상적으로 * card.timeline_items.join (: notes, : attachments) *는 트릭을 완료했을 것입니다).

는이 문제를 해결하기 위해, 나는 내 카드 클래스에 다음 메서드를 추가 :

def timeline 
    (self.notes + self.attachments).sort { |a,b| a.updated_at <=> b.updated_at } 
    end 
+0

내가 솔루션을 게시 주셔서 감사합니다 :) 여기에 내 자신의 질문의 90 %를 대답 것 같아요. –

+0

문제 없음 - 내가 놓친 것이 있으면 알려주세요. – Stu