質問

表すために 3 つのクラスを作成しました , 人々, 、 そして 書籍ローン. 。BookLoans を通じて人々と書籍の関連付けを表示できる間、データベースにシードを加えてきました。

次に、本のチェックアウトを保存する必要があります。このアクションをブック コントローラーを通じて実行するのが私の意図でした。具体的には、BooksController でローン アクションを作成します。これは理論的には理にかなっていますが、適切な構文を実装するのに非常に苦労しています。

本の表示ビューから本を借りる機能を追加しました。このビューには、書籍コントローラーのローン アクションを使用してローンを記録するフォームが含まれるようになりました。

適切だと思われるメソッドを Book モデルに追加しました。の助けを借りて 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 モデルを作成すると、いくつかの追加メソッドにアクセスできます。特に次の 2 つは、 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_idadd_loan, 、それを抽出できます。上記のビューの一部が本の貸し出し用のフォームにラップされていると仮定すると、次の方法でその人物にアクセスできます。 params[:book_loan][:person_id]. 。また、最初にそのアクションで検索を実行することもできます。 @book はゼロになります。

お役に立てれば。乾杯。

編集:今のやり方がうまくいくかどうかはわかりませんが、やり方を変えたいと思っているようです。 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