Domanda

Ho creato tre classi per rappresentare Libri , La gente e BookLoans . Mentre io sono in grado di mostrare l'associazione delle persone ai libri attraverso BookLoans Sono stato semina il mio database.

Ora ho bisogno di salvare un checkout di un libro. Era mia intenzione di fare questa azione attraverso il controller libro. In particolare, la creazione di un'azione di prestito in BooksController. Anche se questo ha senso per me, in teoria, io sto avendo un tempo terribile attuare la sintassi appropriata.

Ho aggiunto la capacità di prestito un libro dalla vista spettacolo di un libro. Questo punto di vista ora contiene una forma che utilizza l'azione di prestito del controller libro per registrare il prestito.

Ho aggiunto che cosa credo sono i metodi appropriati per il mio modello Libro. Con l'aiuto di theIV ho catturato le informazioni appropriate nel controller. Purtroppo, quando si preme di prestito nello show libro visualizzare un record book_loan c'è essere registrati.

Che cosa mi manca?

Prenota Modello

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

Prestito Metodo da BooksController

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

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

Prenota Mostra vista w / Prestito Modulo

<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 %>

BookLoan Modello

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

Persona Modello

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

Sviluppo Log

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
È stato utile?

Soluzione

Quando si has_many un modello, è possibile accedere a un paio di metodi di troppo, due in particolare sono collection.build e collection.create build- è come new, create è come create :). Date un'occhiata alla ha molte documentazione . In questo caso, si potrebbe riscrivere add_loan come

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

o qualcosa di simile.

Per rispondere alla tua domanda su ciò che la vista sarà l'invio al controller, invierà l'hash params come al solito, ma se si desidera solo per passare il person_id a add_loan, è possibile estrarre questo. Supponendo che la parte della vista che avete sopra è avvolto in una forma di un prestito del libro, è possibile accedere alla persona da params[:book_loan][:person_id]. Si potrà anche fare un ritrovamento in quell'azione prima, altrimenti @book sta per essere nullo.

Spero che questo aiuti. Cin cin.

EDIT: Non sono sicuro se il modo in cui lo avete in questo momento funziona, ma penso che si desidera cambiare il vostro modello Person di leggere

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

EDIT 2: Il registro sviluppo dice che non sono in realtà colpire loan, si sta colpendo update. Un paio di cose che si potrebbero fare: controllare per assicurarsi di aver loan come una risorsa quotata in vostri itinerari; unire l'azione loan nel update azione potrebbe iniziare a ricevere sorta di disordinato in modo da non so se questo è l'approccio migliore. Sono sicuro che ci sono più, ma queste sono le prime cose che compaiono in mente. Inoltre, non so se è possibile aggiungere :action => 'loan' a un tag inviare. Penso che sarà basta guardare che, come se si trattasse di un'opzione HTML. Si potrebbe desiderare di cambiare la vostra form_for di leggere

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

una volta che hai fatto in modo che i percorsi sono in ordine. Ma, come ho detto prima, sono abbastanza sicuro che si sarà gettato un errore che l'azione perché non avete definito un Book.find per esso.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top