1)是的,绝对是,控制器“动作”不必处理模型,即
ThingController < ApplicationController
def status
@status = system("#{Rails.root}/lib/mystatusscript");
end
end
当 URL 到达服务器时调用动作,并查询路由表,并确定控制器和动作。所以如果你把它放在你的 routes.rb 中:
match "/whatever" => "things#status"
并输入
http://localhost:3000/whatever
ThingsController (app/controllers/things_controller.rb) 中的状态操作将被调用。
接下来会发生什么,默认情况下,因为你没有告诉它做任何其他事情,rails 将查找 app/views/things/status.html.erb,并渲染它,即:
The stats is <%= @status %>
但是你可以防止这种情况,并让 Rails 做其他事情,可能的例子:
ThingController < ApplicationController
def status
@status = system("#{Rails.root}/lib/mystatusscript");
render :js=>"$('#status_retreived').show();"
end
end
ThingController < ApplicationController
def status
system("#{Rails.root}/lib/do_something_server_side");
render :nothing=>true
end
end
ThingController < ApplicationController
def status
@status = system("#{Rails.root}/lib/mystatusscript");
render action=>:edit
end
end
额外的
让我们做一个表格,看看会发生什么
假设你在 app/views/things/edit.html.erb 中有这个:
<%= form_for @thing do |f| %>
<%= f.input :name %>
<%= f.submit %>
<% end %>
假设您在 routes.rb 中有这些路线:
get '/things/:id/edit' => 'things#edit'
put '/things/:id/update' => 'things#update'
你的控制器有:
def update
@thing = Thing.find(params[:id])
@thing.attributes = params[:thing]
@thing.save
end
def edit
@thing = Thing.find(params[:id])
end
所以这是流程,你用'/things/100/edit'点击你的应用程序
调用编辑操作,实例变量@thing 设置为id 为100 的记录。然后呈现edit.html.erb 视图,显示名称字段的编辑屏幕和提交按钮。
当您单击“提交”时,您将 PUT 到“/things/100/update”
由于路径被定义为“/things/:id/update”的方式,当您进入更新操作时,params[:id] 将包含 100,并且 params[:thing] 将包含表单发布的内容,即您的参数可能包含:
params[:thing][:name]
params[:thing][:city]
....
params[:thing][:zip]
ID被抽象成params[:id],表单数据在params[:thing]
更多的
rails 为你做了很多自动 url 生成,它非常聪明,例如,在 edit.html.erb 中,你有这个:
<%= form_for @thing do |f| %>
<%= f.input :name %>
<%= f.submit %>
<% end %>
如果您查看生成的 HTML,您会看到如下内容:
<form id="edit_thing_100" method="put" action="/things/100/update">
rails 是如何知道进行更新而不是创建的?因为它检查了@thing 并注意到它之前已经保存到数据库中,所以它不是新记录,所以它必须是更新。
因此,在您看来,您通常会创建各种 URI,这些 URI 通过链接、提交按钮等发送到服务器。当在 routes.rb 中查找它们时,会调用相应控制器中的相应操作。
上传文件
比您想象的要容易,首先您需要添加文件上传字段并稍微更改表单:
<%= form_for @thing do ,:html=>{:multipart=>true} |f| %>
<%= f.input :name %>
<%= f.file_field :upload %>
<%= f.submit %>
<% end %>
现在,在更新操作中,您可以执行以下操作:
def update
filename = params[:thing][:upload].original_filename
filetype = params[:thing][:upload].content_type
filedata = params[:thing][:upload].read
File.open("#{Rails.root}/filestorage/#{filename}","wb") { |f| f.write(filedata) }
@thing = Thing.find(params[:id])
@thing.attributes = params[:thing]
@thing.uploadstoredin = "#{Rails.root}/filestorage/#{filename}"
@thing.save
end
因为您制作了多部分表单,并且将属性 :upload 声明为 file_field,所以在发布参数时,:upload 参数有三个额外的方法(original_filename、content_type 和 read),Rails MAGIC!