2012-12-04 2 views
1

의 내가 몇 가지 모델을 가상의 예술 상점을 실행 (및 모델에 의해 내가 레일 용어되지 누드 모델로 예술 용어 말하는 겁니다)이 같이 보입니다 가정 해 봅시다 :레일 : 기존 모델에 has_many 연관을 트랜잭션 방식으로 추가하려면 어떻게해야합니까?

class Artwork < ActiveRecord::Base 
    belongs_to :purchase 
    belongs_to :artist 
end 

class Purchase < ActiveRecord::Base 
    has_many :artworks 
    belongs_to :customer 
end 

Artwork 언젠가 나중에 그것은 Purchase에 포함됩니다. 내 create 또는 updatePurchase에 대한 컨트롤러 방법으로 Purchase을 기존 Artwork에 연결하고 싶습니다.

Artwork 내가 @purchase.artworks.build 또는 @purchase.artworks.create하지만, 이러한을 모두 내가 아닙니다 새로운 Artwork을 만드는거야 가정 수 존재하지 않은 경우. 다음과 같이 기존 아트웍을 추가 할 수 있습니다.

params[:artwork_ids].each do |artwork| 
    @purchase.artworks << Artwork.find(artwork) 
end 

그러나 이것은 트랜잭션이 아닙니다. 데이터베이스가 즉시 업데이트됩니다. (당연히 내가 create 컨트롤러에 있지 않은 한 @purchasesave으로 전화 할 때까지 존재하지 않기 때문에 "트랜잭션으로"수행 할 수 있다고 생각하는 경우가 아니라면 update에 도움이되지 않습니다.) @purchase.artwork_ids= 방법이지만, 즉각적입니다.

나는 이런 일이 update 동작에 효과가있을 것이라고 생각하지만, 매우 우아하지 않습니다.

@purchase = Purchase.find(params[:id]) 
result = @purchase.transaction do 
    @purchase.update_attributes(params[:purchase]) 
    params[:artwork_ids].each do |artwork| 
    artwork.purchase = @purchase 
    artwork.save! 
    end 
end 

종래 다음과 같다 : 내가 무엇을 찾고 있어요 것은 그것이 내가 내 모델에서 accepts_nested_attributes_for을 넣어 수있는 다른 방향에서 작업하는 방법과 같은 것을

if result 
    redirect_to purchase_url(@purchase), notice: 'Purchase was successfully updated.' } 
else 
    render action: "edit" 
end 

입니다 result = @artwork.save으로 전화하면 모든 것이 마술처럼 작동합니다.

답변

1

가 도움이되기를 바랍니다. 내 Product MVC의 각 부분을 업데이트해야했습니다.

모델 :

attr_accessible: artwork_ids 

내가 이전에 포함되지 이후 attr_accessible하는 artwork_ids를 추가했다.

보기 : 내보기에서

= check_box_tag "purchase[artwork_ids][]", artwork.id, artwork.purchase == @purchase 

은 내가 각 작품에 대한 배열을 가지고있다. 나는 상자를 체크하지 않으면 아트웍 ID 대신에 "true"라는 숨겨진 값이 보내지는 곳이 있기 때문에 check_box을 사용할 수 없었다. 그러나 이로 인해 구매에서 모든 삽화를 삭제하는 문제가 발생합니다. update을 수행 할 때 각 확인란의 선택을 취소하면 params[:purchase] 해시에는 :artwork_ids 항목이 없습니다.

컨트롤러 :이 값이 설정되고, 기존의 모든 연결을 제거 원하는 효과를있을 것이라는 점을 보장 추가

params[:purchase][:artwork_ids] ||= [] 

. 그러나 이것은 :update_attributes이 실제로 {"these"=>"params", "artwork_ids"=>[]})을 수신했기 때문에 성가신 rspec 실패를 야기합니다. Purchase.any_instance.should_receive(:update_attributes).with({'these' => 'params'})이 실패합니다. 대신보기에서 hidden_value_tag을 설정하려고 시도했지만 작동시키지 못했습니다. 나는이 니트가 새로운 질문에 합당하다고 생각한다.

+0

두 번째 생각 '= hidden_field_tag'구매 [artwork_ids] [] "는 효과가있는 것처럼 보입니다. – Geoff

+0

방금 ​​전 Railkeet 17이라는 것을 깨달았습니다. 전에도 보았지만, HABTM을 사용했기 때문에 잊어 버린 것 같습니다. – Geoff

0

구매 모델을 조인 테이블로 설정하고 다 대다 관계를 갖는 것이 가장 좋습니다.

다음은 사용 예입니다.

고객 모델

has_many :purchases 

    has_many :artwork, :through => :purchase 

작품 모델

has_many :purchases 

    has_many :customers, :through => :purchase 

구매 모델

belongs_to :customer 
    belongs_to :artwork 

구매 모델은 CUSTOMER_ID와 artwork_id을 포함해야합니다.

또한 새 구매 객체를 만들 수있는 구매 컨트롤러를 만들어야합니다.

고객이 구매 버튼을 누르면 customer_id 및 artwork_id가 포함 된 새로운 구매 객체가 생성됩니다. 이를 통해 고객과 고객이 구매 한 작품을 연관 지을 수 있습니다. price_paid 열을 사용하여 고객이 구매할 때 지불 한 가격을 저장할 수도 있습니다.

더 많은 도움이 필요하면 다음을 사용하여 많은 관계에 참여할 수 있습니다.

내가 상당히 우아한하는 원하는 것을 할 수있는 방법을 알아 낸

+0

제안 해 주셔서 감사합니다. 불행히도, 나는'has_many'가되기 위해'Purchase'가 필요하다는 것을 의미하는 몇 개의 서로 다른 작품을 포함시키기 위해 구매해야합니다. – Geoff

+0

카트 젬을 사용할 수는 있지만 처음부터 다시하고 싶다면. 내가 장바구니에 여러 삽화를 추가 할 수있는 장바구니 모델을 만들면 고객이 실제로 장바구니에있는 항목을 구입할 때 고객에게 주문을 연결하고 여러 삽화를 표시 할 수 있습니다 –