Pregunta

He creado tres clases para representar Libros , Personas y BookLoans . Mientras estoy en condiciones de demostrar la asociación de personas a través de libros BookLoans he estado sembrando mi base de datos.

Ahora necesito guardar un pago y envío de un libro. Era mi intención de hacer esta acción a través del controlador libro. En concreto, la creación de una acción de préstamo en el BooksController. Si bien esto tiene sentido para mí, en teoría, estoy teniendo un tiempo terrible implementar la sintaxis adecuada.

He añadido la capacidad de prestar un libro de la vista de presentación de un libro. Esta vista contiene ahora una forma que utiliza la acción del controlador de préstamo de libros para registrar el préstamo.

He añadido lo que creo son los métodos apropiados a mi modelo de libro. Con la ayuda de theIV he capturado la información apropiada en el controlador. Por desgracia, cuando pulso préstamo en el libro muestran ver un registro book_loan hay ser grabada.

¿Qué me falta?

libro Modelo

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

Método de Préstamo BooksController

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

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

Mostrar vista del libro w / Formulario de Préstamo

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

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

Persona Modelo

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

Iniciar sesión Desarrollo

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
¿Fue útil?

Solución

Cuando has_many un modelo, se obtiene acceso a un número de métodos adicionales, dos en particular son collection.build y collection.create build- es como new, create es como create :). Echar un vistazo a la tiene muchas documentación . En este caso, se puede reescribir como add_loan

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

o algo similar.

Para responder a su pregunta acerca de lo que la vista va a enviar al controlador, se enviará el hash params como de costumbre, pero si lo que desea es pasar el person_id a add_loan, se puede extraer de eso. Suponiendo que la parte de la vista arriba tenemos es envuelto en una forma para un préstamo de libro, se puede acceder a la persona por params[:book_loan][:person_id]. Usted también querrá hacer un hallazgo de que la acción primera, o de lo contrario @book va a ser nula.

Espero que esto ayude. Saludos.

Edit: No estoy seguro de si la forma en que lo tienes en este momento funciona, pero creo que desee cambiar su modelo Person para leer

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

EDIT 2: Su registro desarrollo dice que no está realmente golpeando loan, que está golpeando update. Unas pocas cosas que podría hacer: comprobar para asegurarse de que haya loan como un recurso que aparece en su rutas; combinar la acción loan en el update acción podría empezar a recibir clase de desordenado, así que no sé si este es el mejor enfoque. Estoy seguro de que hay más, pero esas son las primeras cosas que aparecen a la mente. Además, no sé si se puede añadir :action => 'loan' a una etiqueta de envío. Creo que sólo se mira eso como si fuera una opción HTML. Es posible que desee cambiar su form_for para leer

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

Una vez que se haya asegurado de que las rutas están en orden. Pero como he dicho antes, estoy bastante seguro de que te metan un error en esa acción porque no se ha definido un Book.find por ello.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top