0

Ruby-on-railsのカスタムフォームを使って、ほぼすべてのことを幸せにできましたが、最後のステップが欠落しており、一般的な単語が多すぎるため、ネット上で答えを見つけることができません。

私の質問への答えは、しばらくの間RoRを行ったことがある人にとっては些細なことだと思いますが、質問の提示はやや複雑になることに注意してください。

同等の問題を見てみましょう!

スキーマ:

  • publishers (id, name, address)

  • books (id, title, publisher_id, publishing_year, unit_price, qty)

  • sell_log (id, user_id, timestamp, book_id, qty, unit_price, comment)

カスタムアクション:

  • 名前:販売(コンテキスト:本)

  • 入力:qty、、comment(暗黙の入力:book.id、;timestamp派生入力:user_id、、book.unit_pricebook.qty

  • 結果:

    • Sell_logが追加されます

    • books.qtyが減少しました

  • 考えられるエラー:

    • 数量は非正または非整数です。

    • ユーザー入力の数量が利用可能な数量(book.qty)よりも大きい

(参考:データベース設計についての質問ではありません。)

したがって、本の「編集」()と同様の動作でアクションとして実装するカスタムフォーム(非表示のbook-id; qty、comment)がありupdateます。何が行われるか(ほとんどすべてです):

--books_controller.rb:custom_qty_display列を追加しました。

--books_helper.rb:

def custom_qty_display_column(record)
  record.qty.to_label + " ["
  link_to( "Sell..." \
            , { :controller => "books", :action => "sell_form", :id => record.id, :page => false } \
            , { :position => "replace", :inline => true, :class => "action" } \
          ) \
  + "]"
end

--views / books / Sell_form.erb(重要な詳細のみ)

<%
  form_remote_tag( \
    :url => { :controller => :books, :action => :sell, :id => params[:id] } \
  ) do
%>
...
<%= submit_tag 'Submit' %>
<%= link_to as_(:cancel), main_path_to_return, :class => 'cancel' %>
<% end %>
<div id="as_books-messages" class="messages-container" />

--books_controller.rb:

def sell
  errors = [] # We will collect error messages here
  # Checking parameters ...
  # Checking of available qty ...
  # If "errors" is still empty here, perform the action
  # Produce the output according to the above:
  if request.xhr?
    if errors.empty?
      # Q1: rendering of javascript which replaces the form with the modified row in the table.
    else
      # Q2: rendering of javascript which provides the "errors" for the user
    end
  else
    if errors.empty?
      index
    else
      # Q3: Redisplay the form and errors
    end
  end
end

現在の進行

ブックリストのエントリで[販売...]リンクをクリックすると、エントリが消え、代わりにカスタムフォームが表示されます。フォームの[キャンセル]リンク(および[X]ボタン)は完全に機能します。送信ボタンが機能します(入力が正しい場合、アクションは正常に完了します)。

そこにないのは、フォームがそのまま残っているということです。Q1理論的には、、、Q2およびでマークされた場所に適切なJavaScriptを返す必要がありQ3ます。フレームワークのアップグレード時にこの手順をやり直す必要があるため、リバースエンジニアリングを行ってJavaScriptを手作業で作成することは望ましくありません。シンプルさと保守性に関して、必要なJavaScriptを可能な限り最善の方法で作成したいと思います。私が今信じているように、私のコンセプトは悪くありません。

バージョン情報

  • JRuby 1.5.0
  • 宝石
    • レール2.3.4
    • activerecord 2.3.4
    • activesupport 2.3.4

(他に必要なものがあれば教えてください)

部分的な結果

# ...
if errors.empty?
  render :action => 'on_update.js'
else
  # ...
end
# ...
4

2 に答える 2

1

アプリが使用しているRailsのバージョンはどれですか?アプリはどのjavascriptライブラリを使用していますか?BookとSellLogはRESTfulなリソースですか?

link_to_remoteそれらは、ヘルパーで使用しておらずrespond_to、コントローラーアクションでブロックしている理由ですか?

プロトタイプを使用するRails2.3では、次のようにします。

in controller:

def sell 
  # …
  # book / quantity / errors
  # …
  respond_to do |format|
    if errors.empty?
      format.js {render :update do |page|
        page.replace_html '_ID_OF_DOM_OBJECT_CONTAINING_ROW_INFO_', :partial => '_PARTIAL_FOR_ROW_INFO_LAYOUT_' 
      end}
      format.html { redirect_to :action => _WHATEVER_THE_SUCCESS_ACTION_IS_ }
    else
      format.js {render :update do |page|
        page.replace_html 'form', :partial => '_DOM_ID_OF_FORM_' 
      end}
      format.html { render :action => _WHATEVER_ACTION_DISPLAYED_THE_FORM_ }
    end
  end
end

_PARTIAL_FOR_ROW_INFO_LAYOUT_は次のようになります。

<div id="_ID_OF_DOM_OBJECT_CONTAINING_ROW_INFO_">
  <!-- row display markup -->
</div>

Railsの規則に従うと、多くの作業が簡単になりますが、Railsのバージョン、アプリのDSL、またはアプリがコントローラーの現在のパターンを説明するプラグインやgemを使用しているのかわかりません。

于 2010-08-28T19:20:58.543 に答える
0

ステップ1:link_toヘルパーを変更して含める必要がありますeid

link_to( "Close..." \
    , { :controller => "books", :action => "sell_form", :id => record.id, :page => false, :eid => @controller.params[:eid] } \
    , { :position => "replace", :inline => true, :class => "action" } \
  )

ステップ2:を変更し、、、を設定sell_form.erbする必要があります。をに設定する必要があります。また、を使用してフォームの適切なHTMLIDを生成する必要があります。parent_modelparent_columnnestedeidurlupdatebook_listelement_from_id()

<%
  form_remote_tag( \
    :url => { :controller => :books, :action => :sell, :id => params[:id], :parent_column => "books", :parent_model => "Publisher", :nested => "true", :eid => params[:eid] } \
    , :update => :book_list \
    , :html => { :id => element_form_id(:action => :update) } \
  ) do
%>

ステップ3:if request.xhr?パーツを次の簡単なコードに変更します。(完全にはテストされていません。最良のケースは適切に機能します。)

if request.xhr?
  if @record.valid?
    render :action => 'on_update.js'
  else
    render :action => 'form_messages.js'
  end
else
  if @record.valid?
    return_to_main
  else
    render :action => 'sell_form'
  end
end
于 2010-09-02T09:08:28.700 に答える