代码之家  ›  专栏  ›  技术社区  ›  Notinlist

RoR:如何处理自定义嵌套表单的提交

  •  0
  • Notinlist  · 技术社区  · 15 年前

    我用rubyonrails定制了一个表单,几乎一路实现了幸福,但是最后一步没有完成,因为太多的常用词,所以在网上找不到答案。

    我相信对我的问题的回答对于那些做过一段时间的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)

    自定义操作:

    • 名称:Sell(上下文:一本书)

    • qty , comment ,(隐式输入: book.id , timestamp ;派生输入: user_id , book.unit_price , book.qty )

      • 附加销售日志

    • 可能的错误:

      • 数量为非正或非整数。

      • 用户输入的数量大于可用数量(账面数量)

    (仅供参考:这不是关于数据库设计的问题。)

    因此,我们有一个自定义表单(hidden book id;qty,comment),我们希望以类似于“编辑”图书的行为将其实现为一个操作( update ). 所做的(几乎就是一切):

    --书籍_控制器.rb:已添加 custom_qty_display 列。

    --书籍_助手.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
    

    --浏览/书籍/销售_表格.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" />
    

    --书籍_控制器.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 Q3 . 我不想逆向工程和手工编写javascripts,因为在框架升级时,我将被迫重做这一步。我想以最好的方式生成必要的javascript,以实现简单性和可维护性。我相信现在我的观念还不错。

    版本信息

    • JRuby 1.5.0版
    • 宝石
      • 轨道2.3.4
      • 主动支持2.3.4

    (如果还需要什么,请告诉我)

    部分结果

    # ...
    if errors.empty?
      render :action => 'on_update.js'
    else
      # ...
    end
    # ...
    
    2 回复  |  直到 15 年前
        1
  •  1
  •   inkdeep    15 年前

    应用程序使用哪个Rails版本?

    他们是你不使用的原因吗 link_to_remote respond_to 控制器动作中的块?

    Rails 2.3使用prototype时,我是这样做的:

    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
    

    _行信息布局的部分内容将有:

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

        2
  •  0
  •   Notinlist    15 年前

    第一步:你必须修改 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" } \
      )
    

    sell_form.erb 并设置 parent_model , parent_column , nested 开斋节 url update book_list ,并且必须为具有 element_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
    %>
    

    第三步:修改 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
    
    推荐文章