PHPFixing
  • Privacy Policy
  • TOS
  • Ask Question
  • Contact Us
  • Home
  • PHP
  • Programming
  • SQL Injection
  • Web3.0

Friday, October 21, 2022

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

 October 21, 2022     has-many, relationships, ruby-on-rails, ruby-on-rails-3     No comments   

Issue

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 ^^


Solution

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

The base problem is here:

<%= link_to "", wiki_collaborator_path(@wiki, @collaborators), method: :delete, remote: true, class: "glyphicon glyphicon-remove"  %>

The error states that your @collaborators var does not pass the singular id to the link_to method. This is because I presume @collaborators to be a collection.

--

You need to pass a single collaborator object:

<%= link_to "", wiki_collaborator_path(@wiki, c) ...

Since you're using a .each loop with @wiki.users, each user (which I presume to be a collaborator) has the local variable of c assigned:

<% @wiki.users.each do |c| %>

Since you're new, I'd strongly recommend using font-awesome-rails over glyphicon. The main benefit is the fa_icon helper, which would allow you to use:

<%= link_to fa_icon("close"), wiki_collaborator_path(@wiki, c), method: :delete, remote: true %>


Answered By - Richard Peck
Answer Checked By - Marilyn (PHPFixing Volunteer)
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg
Newer Post Older Post Home

0 Comments:

Post a Comment

Note: Only a member of this blog may post a comment.

Total Pageviews

Featured Post

Why Learn PHP Programming

Why Learn PHP Programming A widely-used open source scripting language PHP is one of the most popular programming languages in the world. It...

Subscribe To

Posts
Atom
Posts
Comments
Atom
Comments

Copyright © PHPFixing