Rails 4/ UJS - ActionController::UnknownFormat - 为用户提供一种直接打开模态已经打开的页面的方法
Rails 4/ UJS - ActionController::UnknownFormat - provide user with a way to directly open page with modal already opened
在我的 Ruby Rails 应用程序中,我使用 Ajax 通过 Rails' UJS(不显眼 JavaScript)。
它完美地工作:当用户在交易页面上,然后当他点击某个文本 link 时,会进行 Ajax 调用,并且带有远程内容的模式是已加载。
但我想为用户提供一种方法,让他们可以直接到达已经打开模式的页面,而无需加载交易页面,然后点击文本 link。
例如,用户可以收到一封电子邮件并单击它,他会立即到达已经打开模式的交易页面。
但是它不起作用,当我采用模式的路线(见下面的代码)并在浏览器中输入 http://myapp.com/deals/:id/deal_opportunities_modal 时,它给出了以下错误:
在 29 毫秒内完成 406 不可接受
ActionController::UnknownFormat - ActionController::UnknownFormat:
动作包 (4.2.0) lib/action_controller/metal/mime_responds.rb:218:in respond_to'
app/controllers/deals_controller.rb:70:in
show_opportunities'
这是我的文件:
controller/deals_controller.rb
# used so that old urls created for deals redirects to the new ones created
# indeed with friendly_id, the url is taken from the title :/deals/title
# but if we edit the deal title to deal/title2, the old url was still working
# we need to redirect the old url
# source - github.com/norman/friendly_id/issues/385
before_filter :find_deal,
:only => [ :showcase ]
before_filter :ensure_canonical_deal_path!,
:only => [ :showcase ]
def showcase
@deal = Deal.friendly.find(params[:id])
respond_to do |format|
format.html # showcase.html.erb
format.json { render json: @deal }
end
end
def show_opportunities
@deal = Deal.friendly.find(params[:id])
@opportunity = Opportunity.where('deal_id = ? AND deal_type = ?',
@deal.id, "high tech").first
respond_to do |format|
format.js
end
end
protected
def find_deal
@deal = Deal.friendly.find params[:id]
end
def ensure_canonical_deal_path!
if request.path != deal_page_path(@deal)
redirect_to deal_page_path(@deal, :format => params[:format]), :status => :moved_permanently
return false
end
end
app/views/deals/showcase.html.erb
<% if @deal.present? %>
this is the beginning
<%= render 'deals/deal_info_zone' %>
this is the end
<% end %>
views/deals/_deal_info_zone.html.erb
<div id="zoneA">
<div style="color:red;padding-top: 150px;">
<%= link_to "view infos of the latest Opportunity", deal_opportunities_modal_path, remote: true %>
</div>
</div>
views/deals/deal_opportunities_modal.js.erb
这是通过 Ajax 的模态触发器:views/deals/opportunity_modal。请注意我在这里是如何尝试通过 Deal 但没有成功的,因此行
$('body').append('<%= j render partial: "deals/deal_opportunities_modal" %>');
$('#myModal').modal('show');
/app/views/deals/_deal_opportunities_modal.html.erb
现在是模态view/content:
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-body">
this the the latest opportunity: <%= @opportunity.name %> <br/>
</div>
</div>
</div>
</div>
routes.rb
match '/deals/:id', # this is the Deal page
to: 'deals#showcase',
via: 'get',
as: :deal_page
match '/deals/:id/opportunity_modal',
to: 'deals#show_opportunities',
via: 'get',
as: :deal_opportunities_modal
如何实现这一点,即如何创建一种 route/URL 当用户使用时,他到达交易页面时模式 'show_opportunites' 已经打开。
我听说过 js-routes,但它似乎还有其他用途(即在 javascript 文件中使用 Rails 路由)。
如果我让用户能够像这样使用已经打开的模式访问页面,是否也会存在安全问题?
您不能让浏览器打开只能作为 JS 使用的控制器操作。
在我看来,因为您在交易页面上已经有一个打开模式的按钮,如果他们点击右边就触发它 URL
使用带有调用相同视图的单独控制器动作的路由,存储一个变量来告诉视图使用模态
像这样:
- 给定 link "/deals/24/opportunities" 或任何其他命名约定创建路由:
get '/deals/:id/opportunities', to: "deals#opportunities", as: deal_opportunities
- 在您的控制器中,创建一个使用与
showcase
相同的视图但将变量传递给视图以检查参数 @show_modal = true
的操作
def opportunities
@show_modal = true
@deal = Deal.friendly.find(params[:id])
respond_to do |format|
format.html { render action: "/deals/show" }
end
end
- 在您的
showcase
视图中,如果 show_modal 存在,则使用 javascript 触发视图中已有的按钮以手动调用模态
<%= if @show_modal %>
<script type="text/javascript">
$(window).load(function(){
$("a.deals-button").trigger("click");
});
</script>
<% end %>
在我的 Ruby Rails 应用程序中,我使用 Ajax 通过 Rails' UJS(不显眼 JavaScript)。
它完美地工作:当用户在交易页面上,然后当他点击某个文本 link 时,会进行 Ajax 调用,并且带有远程内容的模式是已加载。
但我想为用户提供一种方法,让他们可以直接到达已经打开模式的页面,而无需加载交易页面,然后点击文本 link。 例如,用户可以收到一封电子邮件并单击它,他会立即到达已经打开模式的交易页面。
但是它不起作用,当我采用模式的路线(见下面的代码)并在浏览器中输入 http://myapp.com/deals/:id/deal_opportunities_modal 时,它给出了以下错误:
在 29 毫秒内完成 406 不可接受
ActionController::UnknownFormat - ActionController::UnknownFormat:
动作包 (4.2.0) lib/action_controller/metal/mime_responds.rb:218:in respond_to'
app/controllers/deals_controller.rb:70:in
show_opportunities'
这是我的文件:
controller/deals_controller.rb
# used so that old urls created for deals redirects to the new ones created
# indeed with friendly_id, the url is taken from the title :/deals/title
# but if we edit the deal title to deal/title2, the old url was still working
# we need to redirect the old url
# source - github.com/norman/friendly_id/issues/385
before_filter :find_deal,
:only => [ :showcase ]
before_filter :ensure_canonical_deal_path!,
:only => [ :showcase ]
def showcase
@deal = Deal.friendly.find(params[:id])
respond_to do |format|
format.html # showcase.html.erb
format.json { render json: @deal }
end
end
def show_opportunities
@deal = Deal.friendly.find(params[:id])
@opportunity = Opportunity.where('deal_id = ? AND deal_type = ?',
@deal.id, "high tech").first
respond_to do |format|
format.js
end
end
protected
def find_deal
@deal = Deal.friendly.find params[:id]
end
def ensure_canonical_deal_path!
if request.path != deal_page_path(@deal)
redirect_to deal_page_path(@deal, :format => params[:format]), :status => :moved_permanently
return false
end
end
app/views/deals/showcase.html.erb
<% if @deal.present? %>
this is the beginning
<%= render 'deals/deal_info_zone' %>
this is the end
<% end %>
views/deals/_deal_info_zone.html.erb
<div id="zoneA">
<div style="color:red;padding-top: 150px;">
<%= link_to "view infos of the latest Opportunity", deal_opportunities_modal_path, remote: true %>
</div>
</div>
views/deals/deal_opportunities_modal.js.erb
这是通过 Ajax 的模态触发器:views/deals/opportunity_modal。请注意我在这里是如何尝试通过 Deal 但没有成功的,因此行
$('body').append('<%= j render partial: "deals/deal_opportunities_modal" %>');
$('#myModal').modal('show');
/app/views/deals/_deal_opportunities_modal.html.erb
现在是模态view/content:
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-body">
this the the latest opportunity: <%= @opportunity.name %> <br/>
</div>
</div>
</div>
</div>
routes.rb
match '/deals/:id', # this is the Deal page
to: 'deals#showcase',
via: 'get',
as: :deal_page
match '/deals/:id/opportunity_modal',
to: 'deals#show_opportunities',
via: 'get',
as: :deal_opportunities_modal
如何实现这一点,即如何创建一种 route/URL 当用户使用时,他到达交易页面时模式 'show_opportunites' 已经打开。
我听说过 js-routes,但它似乎还有其他用途(即在 javascript 文件中使用 Rails 路由)。
如果我让用户能够像这样使用已经打开的模式访问页面,是否也会存在安全问题?
您不能让浏览器打开只能作为 JS 使用的控制器操作。
在我看来,因为您在交易页面上已经有一个打开模式的按钮,如果他们点击右边就触发它 URL
使用带有调用相同视图的单独控制器动作的路由,存储一个变量来告诉视图使用模态
像这样:
- 给定 link "/deals/24/opportunities" 或任何其他命名约定创建路由:
get '/deals/:id/opportunities', to: "deals#opportunities", as: deal_opportunities
- 在您的控制器中,创建一个使用与
showcase
相同的视图但将变量传递给视图以检查参数@show_modal = true
的操作
def opportunities
@show_modal = true
@deal = Deal.friendly.find(params[:id])
respond_to do |format|
format.html { render action: "/deals/show" }
end
end
- 在您的
showcase
视图中,如果 show_modal 存在,则使用 javascript 触发视图中已有的按钮以手动调用模态
<%= if @show_modal %>
<script type="text/javascript">
$(window).load(function(){
$("a.deals-button").trigger("click");
});
</script>
<% end %>