如何 DRY 在所有操作中都相同的 respond_to?
how to DRY a respond_to that is the same in all actions?
我有一个控制器可以为小部件提供服务:
class WidgetsController < ApplicationController
def widget1
respond_to do |format|
format.html
format.js { render js: js_constructor }
end
end
def widget2
respond_to do |format|
format.html
format.js { render js: js_constructor }
end
end
private
def js_constructor
content = render_to_string(params[:action], layout: false)
"document.write(#{content.to_json})"
end
end
这个控制器会变大,所以我想避免在所有操作中重复这段代码:
respond_to do |format|
format.html
format.js { render js: js_constructor }
end
有什么想法吗?
编辑:只是为了提供一些背景...
路线是flexible/dynamic:get 'widgets/:action', to: 'widgets#:action'
因此,如果我访问 widgets/widget1
,它将呈现视图 widget1.html.erb
。
如果我将脚本包含在另一台服务器中,它将在那里构建 widget1:
<script type='text/javascript' src='http://localhost:3000/widgets/widget1.js'></script>
答案是元编程:
class WidgetsController < ApplicationController
[:widget1, :widget2].each do |name|
define_method(name) do
respond_to do |format|
format.html
format.js { render js: js_constructor }
end
end
end
private
def js_constructor
content = render_to_string(params[:action], layout: false)
"document.write(#{content.to_json})"
end
end
我会编写一个将 "view" 作为参数的动作。您基本上是在执行呈现不同视图的 #show
操作。
get 'widgets/:template', to: 'widgets#show'
class WidgetsController < ApplicationController
def show
respond_to do |format|
format.html { render params.require(:template) }
format.js { render js: js_constructor }
end
end
private
def js_constructor
content = render_to_string(params.require(:template), layout: false)
"document.write(#{content.to_json})"
end
end
我有一个控制器可以为小部件提供服务:
class WidgetsController < ApplicationController
def widget1
respond_to do |format|
format.html
format.js { render js: js_constructor }
end
end
def widget2
respond_to do |format|
format.html
format.js { render js: js_constructor }
end
end
private
def js_constructor
content = render_to_string(params[:action], layout: false)
"document.write(#{content.to_json})"
end
end
这个控制器会变大,所以我想避免在所有操作中重复这段代码:
respond_to do |format|
format.html
format.js { render js: js_constructor }
end
有什么想法吗?
编辑:只是为了提供一些背景...
路线是flexible/dynamic:get 'widgets/:action', to: 'widgets#:action'
因此,如果我访问 widgets/widget1
,它将呈现视图 widget1.html.erb
。
如果我将脚本包含在另一台服务器中,它将在那里构建 widget1:
<script type='text/javascript' src='http://localhost:3000/widgets/widget1.js'></script>
答案是元编程:
class WidgetsController < ApplicationController
[:widget1, :widget2].each do |name|
define_method(name) do
respond_to do |format|
format.html
format.js { render js: js_constructor }
end
end
end
private
def js_constructor
content = render_to_string(params[:action], layout: false)
"document.write(#{content.to_json})"
end
end
我会编写一个将 "view" 作为参数的动作。您基本上是在执行呈现不同视图的 #show
操作。
get 'widgets/:template', to: 'widgets#show'
class WidgetsController < ApplicationController
def show
respond_to do |format|
format.html { render params.require(:template) }
format.js { render js: js_constructor }
end
end
private
def js_constructor
content = render_to_string(params.require(:template), layout: false)
"document.write(#{content.to_json})"
end
end