samedi 20 février 2016

How to pass an :id to a link_to through a has_many :through relationship to delete a join table column. (Rails)

This is my first post on StackOverflow, and I'm relatively new to coding in general, so I apologize in advance if I accidentally make some breach of etiquette.

I'm trying to delete a collaborator to a wiki that has been added by the owner, but now he wants to remove their permissions.

This is done from within my wiki#edit view:

<div class="row">
<%= render partial: 'wikis/form' %>
<br>
<%= render partial: 'collaborators/collaborator'%>

<h3> Collaborators: </h3>
<% @wiki.users.each do |c| %>
  <li><%= c.username %></li>
  <% if @wiki.user == current_user && current_user.premium? %>
    <%= link_to "", wiki_collaborator_path(@wiki, @collaborators), method: :delete, remote: true, class: "glyphicon glyphicon-remove"  %>
  <% end %>
<% end %>

The wikis/_form partial is pretty standard:

<div class="col-md-8">

<div class="form-group">
  <%= f.label :title %>
  <%= f.text_field :title, class: 'form-control', placeholder: "Enter wiki title" %>
</div>
<div class="form-group">
  <%= f.label :body %>
  <%= f.text_area :body, rows: 8, class: 'form-control', placeholder: "Enter wiki body" %>
</div>

<% if current_user.admin? || current_user.premium? %>
<div class="form-group">
  <%= f.label :private, class: 'checkbox' do %>
    <%= f.check_box :private %> Private wiki
    <% end %>
</div>
<% end %>

<div class="form-group">
  <%= f.submit "Save", class: 'btn btn-primary' %>
</div>
  <% end %>
</div>

and the collaborators/_collaborator partial creates the initial collaborator:

 <% if @wiki.user == current_user && current_user.premium? %>
  <%= form_for [@wiki, Collaborator.new] do |f| %>
  <%= email_field_tag :collaborator %>
  <%= f.submit "Add collaborator", class: 'btn btn-primary' %>
  <% end %>
<% end %>

This is the Collaborator controller:

  before_action :set_wiki
  def create
    @collaborator = User.find_by_email(params[:collaborator]) #pulled from email tag in collaborator form_for partial
    Collaborator.create(user_id: @collaborator.id, wiki_id: @wiki.id)

    if @collaborator.save
       flash[:notice] = "#{@collaborator.username} at #{@collaborator.email} has been added as a collaborator to #{@wiki.title}"
    else
       flash[:error] = "Adding of collaborator failed"
    end
    redirect_to @wiki
  end

  def delete
    @collaborator = @wiki.users.find(params[:id])

    if @collaborator.destroy
       flash[:notice] = "#{@collaborator.username} at #{@collaborator.email} has been removed from wiki: #{@wiki.title}"
    else
       flash[:error] = "Removal of collaborator failed"
    end
    redirect_to @wiki
  end
private
  def set_wiki
    @wiki = Wiki.find(params[:wiki_id])
  end
end

The Collaborator Model just belongs_to both User and Wiki, and The Wiki model looks like this:

class Wiki < ActiveRecord::Base
  belongs_to :user
  validates :user, presence: true
 #Final refactoring eliminates need for delegate method
 has_many :collaborators, dependent: :destroy
 has_many :users, through: :collaborators
 scope :visible_to, -> (user) { user ? all : where(private: false) }
  validates :title, length: { minimum: 5 }, presence: true
  validates :body, length: { minimum: 20 }, presence: true
end

The error I'm getting back from my local server is

No route matches {:action=>"destroy", :controller=>"collaborators", :id=>nil, :wiki_id=>"104"} missing required keys: [:id]

I've looked everywhere to solve this problem, but I inherently have some trouble understanding the nested routing for has_many :through associations and when I look for answers it seems like everyone has written their method calls differently than mine. Everything in my app functions except this link_to method, so I'd rather not rewrite it just to match someone else's code unless I really messed up somewhere.

I've tried putting @collaborator.id as well as a few other things just to try to brute force a solution, but nothing is working and I have no idea what I'm looking for here.

Any help at all would be greatly appreciated. Thank you ^^

Aucun commentaire:

Enregistrer un commentaire