Rails 4 / UJS - ActionController :: UnknownFormat - 为用户提供一种方式来直接打开已打开模态的页面

时间:2015-09-26 13:34:15

标签: javascript ruby-on-rails ruby-on-rails-3 ujs

在我的Ruby on Rails应用程序中,我通过Rails使用Ajax' UJS(不引人注目的JavaScript)。

它非常有效:当用户在交易页面上,然后当他点击某个文本链接时,会进行Ajax调用并加载具有远程内容的模态。

但是我想让用户直接到达页面,方式是已打开模式,无需加载“交易”页面,然后点击文字链接 。 例如,用户可以收到en电子邮件并点击它,他会立即到达Deal Page并且已经打开了模式。

但它不起作用,当我采用模态的路线(参见下面的代码),并输入浏览器http://myapp.com/deals/:id/deal_opportunities_modal时,它会发出以下错误:

已完成406在29毫秒内无法接受

ActionController :: UnknownFormat - ActionController :: UnknownFormat:   actionpack(4.2.0)lib / action_controller / metal / mime_responds.rb:218:在respond_to' app/controllers/deals_controller.rb:70:in show_opportunities'

以下是我的文件:

控制器/ 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

应用程序/视图/交易/ showcase.html.erb

<% if @deal.present? %>
   this is the beginning
   <%= render 'deals/deal_info_zone' %>
   this is the end
<% end %>

视图/交易/ _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>

视图/交易/ deal_opportunities_modal.js.erb

这是通过Ajax的模态触发器:views / deals / opportunity_modal。请注意我在这里试图通过交易,但没有成功,所以行

$('body').append('<%= j render partial: "deals/deal_opportunities_modal" %>');
$('#myModal').modal('show');

/app/views/deals/_deal_opportunities_modal.html.erb

现在是模态视图/内容:

<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

如何实现这一目标,即如何创建一种路由/ URL,当用户使用时,他会使用模式“show_opportunites&#39;”到达“交易”页面。 已经开放。

我听说过js-routes,但它似乎对其他用途有用(i.E在javascript文件中使用Rails路由)。

如果我允许用​​户使用已打开的模式访问该页面,是否还存在安全问题?

1 个答案:

答案 0 :(得分:1)

您不能让浏览器对仅作为JS提供的控制器操作开放。

我看到它的方式,因为你已经在交易页面上有一个打开模态的按钮,只要它们点击正确的URL就触发它

使用具有单独控制器actiona的路径调用同一视图,存储变量以告知视图使用模态

像这样:

  • 鉴于链接“/ 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 %>