문제

나는 대표 할 세 가지 수업을 만들었습니다 서적, 사람들, 그리고 책장. 나는 책정을 통해 사람들의 협회와 책을 보여줄 수 있지만 데이터베이스를 시드하고 있습니다.

이제 책의 결제를 저장해야합니다. 책 컨트롤러를 통해이 조치를 취하는 것이 저의 의도였습니다. 구체적으로, BooksController에서 대출 조치를 작성합니다. 이것은 이론적으로 나에게 의미가 있지만 적절한 구문을 구현하는 데 끔찍한 시간을 보내고 있습니다.

나는 책의 쇼에서 책을 빌려줄 수있는 능력을 추가했다. 이 견해에는 이제 책 컨트롤러의 대출 조치를 사용하여 대출을 기록하는 양식이 포함되어 있습니다.

내 책 모델에 적절한 방법이라고 생각하는 것을 추가했습니다. 의 도움으로 Theiv 컨트롤러에서 적절한 정보를 캡처했습니다. 불행히도, 책 쇼에서 대출을 누를 때 Book_loan 레코드는 기록되지 않습니다.

내가 무엇을 놓치고 있습니까?

책 모델

class Book < ActiveRecord::Base
  has_many :book_loans
  has_many :borrowers, :through => :book_loans, :source => :person

  accepts_nested_attributes_for :book_loans, :allow_destroy => true

  def loaned?
    book_loans.exists?(:return_date => nil)
  end

  def current_borrower
    if loaned?
      book_loans.first(:order => "out_date desc").person
    end
  end

  def add_loan (person_id)
      book_loans.create(:book_id => id,
                        :person_id => person_id,
                        :out_date => Date.current)
  end
end

BooksController의 대출 방법

def loan
  @book.add_loan(params[:book_loan][:person_id])

  redirect_to :action => 'book', :id => params[:id]
end

대출 양식이있는 책 쇼보기

<p>
  <b>Title:</b>
  <%=h @book.title %>
</p>
<p>
  <b>Isbn10:</b>
  <%=h @book.isbn10 %>
</p>
<p>
  Currently loaned to:
  <%=h borrower_name(@book) %>
</p>

<% form_for(@book) do |x| %>
  <p>
    <%= x.label :loan_person_id %><br/>
    <%= collection_select(:book_loan, :person_id,
      Person.find(:all, :order => 'name ASC'), :id, :name) %>
    <%= x.submit 'Loan', :action => 'loan' %>
  </p>
<% end %>

북서 모델

class BookLoan < ActiveRecord::Base
  belongs_to :book
  belongs_to :person
end

사람 모델

class Person < ActiveRecord::Base
  has_many :book_loans
  has_many :books, :through => :book_loans
end

개발 로그

Processing BooksController#update (for 127.0.0.1 at 2009-09-24 13:43:05) [PUT]
  Parameters: {"commit"=>"Loan", "authenticity_token"=>"XskHLuco7Q7aoEnDfVIiYwVrMEh5uwidvJZdrMbYYWs=", "id"=>"1", "book_loan"=>{"person_id"=>"3"}}
  [4;35;1mBook Columns (3.0ms)[0m   [0mSHOW FIELDS FROM `books`[0m
  [4;36;1mBook Load (4.0ms)[0m   [0;1mSELECT * FROM `books` WHERE (`books`.`id` = 1) [0m
  [4;35;1mSQL (0.0ms)[0m   [0mBEGIN[0m
  [4;36;1mBook Load (1.0ms)[0m   [0;1mSELECT `books`.id FROM `books` WHERE (`books`.`title` = BINARY 'Dreaming in Code: Two Dozen Programmers, Three Years, 4,732 Bugs, and One Quest for Transcendent Software' AND `books`.id <> 1) LIMIT 1[0m
  [4;35;1mSQL (1.0ms)[0m   [0mCOMMIT[0m
Redirected to http://localhost:3000/books/1
Completed in 19ms (DB: 10) | 302 Found [http://localhost/books/1]
  [4;36;1mSQL (0.0ms)[0m   [0;1mSET NAMES 'utf8'[0m
  [4;35;1mSQL (0.0ms)[0m   [0mSET SQL_AUTO_IS_NULL=0[0m
도움이 되었습니까?

해결책

때를 has_many 모델, 몇 가지 추가 방법에 액세스 할 수 있습니다. collection.build 그리고 collection.createbuild 처럼 new, create 처럼 create :). 살펴보십시오 많은 문서가 있습니다. 이 경우 ADD_LOAN을 다시 작성할 수 있습니다

def add_loan (person_id)
  book_loans.create(:book_id   => id,
                    :person_id => person_id,
                    :out_date  => Date.current)
end

또는 비슷한 것.

컨트롤러로 보낼보기에 대한 질문에 답하기 위해 params 평소와 같이 해시이지만, 당신이 그냥 통과하고 싶다면 person_id 에게 add_loan, 당신은 그것을 추출 할 수 있습니다. 위의 견해의 일부가 책 대출 양식으로 싸여 있다고 가정하면 사람에게 액세스 할 수 있습니다. params[:book_loan][:person_id]. 당신은 또한 그 행동에서 먼저 찾을 수 있고, 그렇지 않으면 @book nil이 될 것입니다.

도움이 되었기를 바랍니다. 건배.

편집 : 지금 당장 가지고있는 방식이 작동하는지 확실하지 않지만 변경하고 싶다고 생각합니다. Person 읽을 모델

class Person < ActiveRecord::Base
  has_many :book_loans
  has_many :books, :through => :book_loans
end

편집 2 : 개발 로그는 실제로 타격이 없다고 말합니다. loan, 당신은 맞습니다 update. 당신이 할 수있는 몇 가지 : 당신이 가지고 있는지 확인하십시오. loan 노선에서 나열된 리소스로; 병합 loan 행동으로의 행동 update 행동 - 지저분해질 수 있으므로 이것이 최선의 접근 방식인지 모르겠습니다. 나는 더 많은 것이 있다고 확신하지만, 그것들은 가장 먼저 떠오르는 것들입니다. 또한 추가 할 수 있는지 모르겠습니다 :action => 'loan' 제출 태그에. 마치 HTML 옵션 인 것처럼 볼 것이라고 생각합니다. 당신은 당신의 변화를 원할 수도 있습니다 form_for 읽다

<% form_for(@book), :url => { :action => 'loan' } do |x| %>

일단 경로가 순서대로 확인되면 하지만 앞서 말했듯이, 나는 당신이 Book.find 그것을 위해.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top