I have an event management page which contains two partials, one with the partners not yet invited to the event, one with the partners invited to the event. Partners can either be added to the event (other_partners collection) or be removed (current_partners collection).
Strange behavior depending on order of actions
Delete then create => Everything is ok, I can add and remove with no limit
Once the page loaded, I can remove partner (method: :delete) whithout any problem, partner disappear from current_partners collection (partial) and appears in other_partners collection (partial). If a try to add a partner, it works and the partner is added to current_partners collection and removed from other_partners collection
Create then GET 500 ERROR => Rails seems to ignore ujs
Once the page loaded, If I click on a partner inside other_partner partial to add (method: :post) it to the event, rails ignores the method: :post and GET the url provided, which causes a 500 error because the action show is not present inside my controller (only create and destroy)
Here is my code :
_other_partner.html.erb
is a partial containing user's partners that don't participate to the event. On click on a partner, it is added to the event, disappear form the other_partners collection and appears in the current_partners collection.
Note that the url looks like /events/1/manage_partners?id=21. I'm passing the id of partner as additional param to create the link between event and partner. I'm not using button because partials already are inside a larger form.
<%= div_for partner, class: "partner__current",
data: { behavior: "partner", id: partner.id } do %>
<%= link_to event_manage_partners_path(event, id: partner.id),
method: :post,
data: { behavior: "create-partner" },
remote: true,
class: "link--primary" do %>
<%= content_tag :div, nil, class: "icon icon__add_circle--black" %>
<% end %>
<% end %>
-
_current_partner.html.erb
is a partial listing all the partners that participates to the event. On click on a partner, it is deleted from the event, disappear from the current_partners collection and appears in the other_partners collection.
<%= div_for partner, class: "partner__current",
data: { behavior: "partner" } do %>
<%= link_to event_manage_partner_path(event, partner),
method: :delete,
remote: true,
class: "link--primary" do %>
<%= content_tag :div, nil, class: "icon icon__cancel_circle--black" %>
<% end %>
<% end %>
-
event.html.erb
<%= render partial: 'partners/other_partner',
collection: @event_facade.other_partners,
as: :partner,
locals: { event: @event_facade.event },
cached: true %>
<% end %>
<%= render partial: 'partners/current_partner',
collection: @event_facade.current_partners,
as: :partner,
locals: { event: @event_facade.event },
cached: true %>
<% end %>
-
create.js and destroy.js (both are similar)
$("[data-behavior='new-partner']").html("<%= j render partial: 'partners/other_partner', collection: @event_facade.other_partners, as: :partner, locals: { event: @event_facade.event }, cached: true %>");
$("[data-behavior='current-partners']").html("<%= j render partial: 'partners/current_partner', collection: @event_facade.current_partners, as: :partner, locals: { event: @event_facade.event }, cached: true %>");
-
events/manage_partner_controller.rb
module Events
class ManagePartnersController < ApplicationController
before_action :set_event
def create # (url looks like /events/1/manage_partners?id=21)
@event_facade = EventFacade.new(@event)
EventPartnerService.new(@event).join_event(params[:id])
respond_to do |format|
format.html { redirect_to edit_event_url(@event) }
format.js # { render layout: false }
end
end
def destroy
@event_facade = EventFacade.new(@event)
EventPartnerService.new(@event).leave_event(params[:id], current_user)
respond_to do |format|
format.html { redirect_to edit_event_url(@event) }
format.js # { render layout: false }
end
end
private
def set_event
@event = current_user.events.find(params[:event_id])
end
end
end
-
layout/application.html.erb
<%= javascript_include_tag 'application', 'data-turbolinks-track' => true %>
-
assets/javascript/application.js (jquery-ujs loaded by bower)
//= require jquery/dist/jquery.min
//= require jquery.turbolinks
//
//= require jquery-ujs/src/rails
//= require turbolinks
-
routes.rb
resources :users, only: [:index, :show], concerns: :paginatable do
resources :events, except: :new, concerns: :paginatable do
resources :manage_partners, controller: 'events/manage_partners', only:[:create, :destroy]
end
end
-
rake routes output
event_manage_partners POST (/:locale)/events/:event_id/manage_partners(.:format) events/manage_partners#create {:locale=>/en-US|fr-FR/}
event_manage_partner DELETE (/:locale)/events/:event_id/manage_partners/:id(.:format) events/manage_partners#destroy {:locale=>/en-US|fr-FR/}
Here is the 500 error:
ActionController::RoutingError (No route matches [GET] "/events/81/manage_partners"):
Rails tries to GET when I specifically ask for POST. The manage_partners_controller.rb doesn't contain an show action, only #create and #destroy, thus the error.
Again, everything works fine except the method: :post which is ignored when the link is clicked just after first page load.
Strange behavior, and I'm pretty clueless here. Please help. Thank you!
Could be cause you are nesting a level too deep, you shouldn't nest resources more then one level deep. Take a look at this http://guides.rubyonrails.org/routing.html#nested-resources
Put this in the header of my page which solved issues with turbolink