我设法用我在 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)
自定义动作:
名称:Sell(上下文:一本书)
输入:
qty
,comment
, (隐式输入:book.id
,timestamp
;派生输入:user_id
,book.unit_price
,book.qty
)结果:
附加了 sell_log
书籍数量减少
可能的错误:
数量是非正数或非整数。
用户输入的数量大于可用数量(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
- 主动记录 2.3.4
- 主动支持 2.3.4
(如果还有什么需要请告诉我)
部分结果
# ...
if errors.empty?
render :action => 'on_update.js'
else
# ...
end
# ...