2010-08-27 42 views
0

我在ruby-on-rails中用自定義表單設法做了幾乎所有的快樂事情,但最後一步已經失蹤,無法找到答案因爲太多的常用詞彙網。RoR:如何處理自定義嵌套表單的提交

我相信我的問題的答案對於一段時間內完成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)

自定義操作:

  • 名稱:賣(上下文:一本書)

  • 輸入:qtycomment,(隱式輸入:book.idtimestamp;衍生的輸入:user_id,,book.qty

  • 結果:

    • sell_log附加

    • books.qty降低

  • 可能的錯誤:

    • 數量是非正數或非整數。

    • 在用戶輸入的數量超出了可用的數量(book.qty)

更大(FYI:這不是一個有關數據庫設計的問題。)

所以我們有一個自定義的表單(隱藏的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 

- 視圖/書籍/ 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]按鈕)完美地工作; SUBMIT按鈕有效(當輸入正確時,操作成功完成)。

什麼是不存在的形式仍然存在。理論上,我應該在標有Q1Q2Q3的地方返回適當的javascript。我不想逆向工程並用手寫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 
# ... 
+0

ARGH ...錯過了問題中的觀點。無論如何,因爲這是與部隊的一週戰鬥。這對宇宙是有價值的(我希望)。請參閱編輯日誌 – Notinlist 2010-09-02 09:09:25

回答

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並設置parent_modelparent_columnnested並在urleid。您必須將update設置爲book_list,並且必須爲element_from_id()的表單生成適當的HTML標識。

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

是該應用使用的是哪個版本的Rails? 該應用使用的是什麼JavaScript庫? 是Book和SellLog RESTful資源嗎?

他們是否在控制器操作中使用幫助器中的link_to_remote塊和respond_to塊?

對於使用Rails的原型2.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,或者你的應用程序使用什麼插件和/或寶石來解釋你的控制器中的當前模式。

+0

我在問題結尾處添加了版本信息。 '_PARTIAL_FOR_ROW_INFO_LAYOUT_'應該有一些微不足道的渲染方式。如果我調試成功的「編輯」('update')動作的響應,我會看到大量的javascript。我希望有人知道生成這些東西所需的幾條線。我繼續挖掘,當我擁有它時,會發布我自己的結果。 差點忘了!你的回答還是教了很多!謝謝 :-) – Notinlist 2010-08-30 09:01:24