2010-08-27 31 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