在这篇指南中,将跟随王牌反抗军飞行员,他们将接近应用程序的表面。他们将通过应用程序的超级结构,建立自己(飞行员)与他们驾驶的星舰之间的关系。
由于所有的重工作都由定义在领域模型中的ActiveRecord配置处理,星舰模型的控制器相当标准。作为快速回顾,这里是ships_controller
中的create
方法的样子:
def create
@ship = Ship.new(params[:ship])
if @ship.save
redirect_to(ships_path, :notice => "The #{@ship.name} ship has been saved successfully.")
else
render(:new, :error => @ship.errors)
end
end
如果对查看完整的控制器感兴趣,可以在这里查看。
借鉴了Railscast,添加了一些辅助方法来简化生活:
module ApplicationHelper
def link_to_remove_fields(name, f, options = {})
f.hidden_field(:_destroy) + link_to_function(name, "remove_fields(this)", options)
end
def link_to_add_fields(name, f, association, options = {})
new_object = f.object.class.reflect_on_association(association).klass.new
fields = f.fields_for(association, new_object, :child_index => "new_#{ association }") do |builder|
render(association.to_s.singularize + "_fields", :f => builder)
end
link_to_function(name, "add_fields(this, '#{ association }', '#{ escape_javascript(fields) }')", options)
end
end
上面的代码几乎是从Railscast中逐字复制的,但认为仍然值得一提:
link_to_remove_fields:这个方法将创建一个隐藏的_destroy
字段(这告诉否应该删除记录),以及一个将调用JavaScript方法来更新_destroy
字段的超链接。
link_to_add_fields:这个方法将:
fields_for方法让看看link_to_add_fields的第二行和第三行(上面显示的代码中的第8行和第9行)。使用fields_for方法为构建飞行员输入字段。在高层次上,fields_for方法允许构建一个HTML表单,而不需要
fields_for方法接受一些参数:
在fields_for块中,要求它渲染_pilot_fields.html.erb部分视图。注意第二个参数,:f => builder是父表单(即包含正在处理的船的输入字段的表单)。这意味着在调用fields_for时渲染的飞行员字段将是“添加船”表单的一部分,这正是想要的。
此时,fields变量应该看起来有点像这样(整理得可以实际阅读):
Add a Pilot
XML
在link_to_add_fields方法的最后一行(上面显示的代码中的第12行),将fields变量的内容传递给link_to_function方法。link_to_function方法将设置一个将调用add_fields JavaScript方法的链接(在下一部分描述)。fields值将用作add_fields方法的content参数。
没有一点JavaScript的网络应用是不完整的。上面显示的辅助方法使用了Rails内置的link_to_function辅助方法。link_to_function将用于调用下面显示的JavaScript方法。
function remove_fields(link) {
$(link).prev("input[type=hidden]").val("1");
$(link).closest(".fields").hide();
}
function add_fields(link, association, content) {
var new_id = new Date().getTime();
var regex = new RegExp("new_" + association, "g");
$(link).parent().after(content.replace(regex, new_id));
$("#new-pilot-fields").modal("show");
}
remove_fields函数相当直接:
add_fields函数有点复杂,但没有什么太花哨的:
非常清楚,fields_for方法描述的HTML将被添加到“添加船”屏幕(还没有看到,但相信 - 它即将到来)。