2014-05-17 2 views
0

레일 3.2를 사용하고 있습니다. "샘플"에 대해 중첩 된 양식이 있습니다. "환자"는 여러 개의 "샘플"을 가질 수 있지만 "샘플"은 하나의 "환자"만 가질 수 있습니다.레코드가 존재하는지 확인하십시오. 업데이트 기타 새로운 내용 - 중첩 된 양식 - 레일

환자 기본 키는 "id"이지만 nid, province_id, district_id 및 facility_id의 4 가지 외래 키도 있습니다. 여기

은 모델 (난 단지 관련 코드를 보여주기 위해 노력하고있어)입니다 :

Patient.rb을

class Patient < ActiveRecord::Base 

    attr_accessible :date_of_birth, :infant_name, :nid, :province_id, :district_id, :facility_id, :gender_id, :gender_atributes 

    belongs_to :gender 
    belongs_to :province 
    belongs_to :district 
    belongs_to :facility 
    has_many :samples 

    accepts_nested_attributes_for :gender 

    validates :province_id, presence: true 
    validates :district_id, presence: true 
    validates :facility_id, presence: true 
    validates :nid, presence: true 
    #To validate uniqueness of patient, that is, one with unique nid, province, district and facility 
    validates_uniqueness_of :nid, :scope => [:province_id, :district_id, :facility_id] 

end 

Sample.rb 내가 원하는 것은 방지하는 것입니다

class Sample < ActiveRecord::Base 
    attr_accessible :dateOfSample, :nrOrdem, :patient_id,:facility_id, :province_id, :district_id 

    belongs_to :facility 
    belongs_to :patient 
    belongs_to :province 
    belongs_to :district 

    accepts_nested_attributes_for :patient 

end 

(nid, province_id, district_id 및 facility_id)와 다른 환자가있는 환자에 대한 손상된 데이터.

지금 샘플의 중첩 된 양식을 사용하면 새 환자를 만들 수 있으며 같은 (nid, province_id, district_id 및 facility_id)로 새 것을 만들려고하면 "nid is taken ".

환자가 다른 샘플을 가질 수 있으므로 레코드를 만들려고 할 때 "patient_id"를 "sample"레코드에 추가하지 않으면 환자가 이미 있는지 확인하고 그렇지 않으면 새로운.

환자가 이미 존재하며 양식의 해당 데이터를 채우는 메시지를 표시하는 것은 좋지만, patient_id가 샘플 레코드에 추가되면 나머지는 무시하고 기꺼이 기다려야합니다. 환자 필드는 중첩 된 형태로 나타납니다.

rails: create Parent, if doesn't exist, whilte creating child record과 같은 것을 구현하려고했지만 작동하지 않았습니다.

나는이 문제를 어떻게 해결할 수 있습니까?

편집

여기에 코드 @ 제임스 메이슨의 도움 후 결국 방법입니다. Sample.rb

def patient_attributes=(attrs) 
    self.patient = Patient.where({:nid => attrs[:nid], province_id: province_id, district_id: district_id, facility_id: facility_id}).first_or_initialize(attrs) 
end 

답변

2

에 당신은 first_or_create and/or first_or_initialize 찾고 있습니다. 이 경우 레코드가 이미 존재하는지 여부에 신경을 썼기 때문에 아마도 초기화 버전을 원할 것입니다.

class Sample < ActiveRecord::Base 
    belongs_to :patient 
    accepts_nested_attributes_for :patient 

    def patient_attributes=(attrs) 
    self.patient = Patient.where(attrs).first_or_initialize(attrs) 
    @show_exists_message = [email protected]_record? 
    end 
end 
+0

나는 "을 만들에 그것을 놓을 게요 : 중첩 된 속성을 사용하고 있기 때문에

@patient = Patient.where({nid: nid, province_id: province_id, district_id: district_id, facility_id: facility_id}).first_or_initialize @show_exists_message = [email protected]_record? @patient.save 

당신은 정의, 사용자 정의 Sample#patient_attributes= 방법을 컨트롤러의 create 행동이 코드를 삽입, 또는 할 수 있습니다 "샘플"컨트롤러의 동작? – lbramos

+0

코드를 어디에 넣을 지에 대한 예제가 업데이트되었습니다. –

+0

거의 다 왔을 것 같습니다. 나는 샘플 모델에 코드를 넣었지만'self.patient = Patient.where ({: nid => attrs [: nid], province_id : province_id, district_id : district_id, facility_id : facility_id})해야만했다. first_or_initialize '를 사용하면이 필드 만 검색 할 수 있습니다. 환자가 이미 존재하는 경우 샘플 레코드에 "patient_id"를 추가 할 수 있지만 환자가없는 경우 환자 attrs의 나머지 부분을 통과시키지 않습니다. 존재하지 않으면 어떻게 나머지를 전달할 수 있습니까? attrs에 params 중? 덕분에 – lbramos