我设法用ruby-on-rails中的自定义表单几乎一直走向幸福,但最后一步是缺失的,因为太多常用词而无法在网上找到答案。< / p>
我相信对于那些已经做过一段时间的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_price
,book.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]按钮)完美地工作; SUBMIT按钮有效(当输入正确时,操作成功完成)。
什么不存在表格仍然存在。理论上,我应该在标有Q1
,Q2
和Q3
的地方返回相应的javascript。我不想反向工程并用手写javascripts,因为在框架升级时我会被迫重做这一步。我希望以简单和可维护性的最佳方式生成必要的javascripts。我相信现在我的概念还不错。
版本信息
(告诉我是否需要其他任何东西)
部分结果
# ...
if errors.empty?
render :action => 'on_update.js'
else
# ...
end
# ...
答案 0 :(得分: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或您的应用使用哪些插件和/或宝石来解释当前的模式你的控制器。
答案 1 :(得分: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_model
中设置parent_column
,nested
,eid
和url
。您必须将update
设置为book_list
,并且必须为包含element_from_id()
的表单生成正确的HTML 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