Frage

ich drei Klassen erstellt haben zu repräsentieren Bücher Menschen und BookLoans . Während ich bin in der Lage, die Vereinigung von Menschen zu Büchern durch BookLoans zu zeigen, ich habe meine Datenbank gewesen Impfen.

Ich brauche jetzt eine Kasse eines Buches zu speichern. Es war meine Absicht, diese Aktion durch das Buch Controller zu tun. Insbesondere ein Darlehen Aktion in dem BooksController zu schaffen. Während dies macht Sinn für mich in der Theorie ich eine schreckliche Zeit habe die entsprechende Syntax implementieren.

Ich habe die Möglichkeit hinzugefügt, ein Buch aus der Show Ansicht eines Buchs zu leihen. Diese Ansicht enthält nun eine Form, die das Darlehen Aktion des Buches Controller verwendet das Darlehen aufzunehmen.

Ich habe hinzugefügt, was ich glaube, dass die entsprechenden Methoden zu meinem Buch Modell sind. Mit Hilfe von theIV Ich habe die entsprechenden Informationen im Controller erfasst. Leider, wenn ich Loan auf dem Buch zeigen drücke ein book_loan Datensatz anzuzeigen aufgezeichnet kein Wesen.

Was bin ich fehlt?

Buch Modell

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

Loan-Methode von BooksController

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

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

Buch Show View w / Leihformular

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

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

Person Modell

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

Entwicklung 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
War es hilfreich?

Lösung

Wenn Sie ein Modell has_many, haben Sie Zugriff auf ein paar zusätzliche Methoden bekommen, zwei insbesondere sind collection.build und collection.create- build ist wie new, create ist wie create :). Haben Sie einen Blick auf die viele Dokumentation hat . In diesem Fall könnte man umschreiben add_loan als

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

oder etwas ähnliches.

Um Ihre Frage zu beantworten, was die Sicht wird an die Steuerung das Senden, wird es den params Hash wie gewohnt schicken, aber wenn Sie nur die person_id add_loan übergeben wollen, können Sie das extrahieren. Unter der Annahme, dass der Teil der Ansicht, die Sie oben haben in einer Form für ein Buch Darlehen gewickelt sind, können Sie die Person, die von params[:book_loan][:person_id] zugreifen können. Sie wollen auch zuerst einen Fund in dieser Aktion zu tun, sonst @book ist gleich Null sein wird.

Hoffe, das hilft. Prost.

EDIT: Ich bin nicht sicher, ob die Art und Weise Sie es gerade jetzt funktioniert, aber ich denke, Sie Person Modell ändern möchten, lesen

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

EDIT 2: Ihre Entwicklung log sagt, Sie sind nicht wirklich loan schlagen, Sie schlagen update. Ein paar Dinge, die Sie tun können: überprüfen, um sicherzustellen, dass Sie als börsennotierte Ressource in Ihren Routen loan; verschmelzen die loan Aktion in die update aktions könnte beginnen Art chaotisch bekommen, damit ich weiß nicht, ob dies der beste Ansatz ist. Ich bin sicher, es gibt mehr, aber das sind die ersten Dinge, die den Sinn Pop. Auch ich weiß nicht, ob Sie :action => 'loan' zu einem einreichen Tag hinzufügen können. Ich denke, es wird nur das betrachten, als ob es sich um eine HTML-Option waren. Vielleicht möchten Sie Ihre form_for ändern lesen

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

, wenn Sie sich vergewissert haben, dass die Wege in Ordnung sind. Aber wie ich bereits sagte, ich bin ziemlich sicher, dass Sie auf diese Aktion ein Fehler ausgelöst werden, da Sie kein Book.find für sie definiert haben.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top