samedi 26 septembre 2015

Rails 4/ UJS - ActionController::UnknownFormat - provide user with a way to directly open page with modal already opened

In my Ruby on Rails application, I am using Ajax through Rails' UJS (unobtrusive JavaScript).

It's perfectly working: when a user is on a Deal page, and when he then clicks on a certain textual link, the Ajax call is made and the modal with the distant content is loaded.

But I'd like to give a way to users to arrive directly on the page WITH the modal ALREADY OPENED, without him needing to load the Deal page and then click on the textual link. For example a user could receive en email and click on it and he would straight away arrive on Deal Page with the modal already opened.

But it's not working, when I take the route of the modal (see code below), and type in the browser http://ift.tt/1Wp6HIf , then it's giving the following error:

Completed 406 Not Acceptable in 29ms

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

Here are my files:

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 - http://ift.tt/1Fm4JUL
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

Here is the modal trigger via Ajax: views/deals/opportunity_modal. Note here how I tried here to pass Deal but without success so that the line

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

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

Here is the modal view/content now:

<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

How to achieve this, i.e. how to create a sort of route/URL that when used by a user, he arrives on Deal page with the modal 'show_opportunites' already open.

I heard about js-routes but it seems to be useful for other purposes (i.E use Rails routes inside javascript files).

Also is there a security issue if I enable the user to reach the page with the already-opened modal like that?

Aucun commentaire:

Enregistrer un commentaire