如何通过 has_many :through 关系将 :id 传递给 link_to 以删除连接 table 列。 (Rails)

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

这是我在 Whosebug 上的第一个 post,总体而言我对编码还比较陌生,所以如果我不小心违反了礼仪,我提前道歉。

我正在尝试删除所有者添加的 wiki 的协作者,但现在他想删除他们的权限。

这是在我的 wiki#edit 视图中完成的:

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

wikis/_form 部分非常标准:

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

并且 collaborators/_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 %>

这是协作者控制器:

  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

协作者模型仅 belongs_to 用户和 Wiki,Wiki 模型如下所示:

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

我从本地服务器返回的错误是

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

我到处寻找解决这个问题的方法,但我在理解 has_many 的嵌套路由方面存在一些问题:通过关联,当我寻找答案时,似乎每个人都以不同的方式编写了他们的方法调用比我的。除了这个 link_to 方法,我的应用程序中的所有功能都起作用,所以我宁愿不重写它只是为了匹配别人的代码,除非我真的在某个地方搞砸了。

我试过放置 @collaborator.id 以及其他一些东西来尝试暴力破解解决方案,但没有任何效果,我也不知道我要在这里寻找什么。

如有任何帮助,我们将不胜感激。谢谢^^

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

基本问题在这里:

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

错误指出您的 @collaborators var 没有将单数 id 传递给 link_to 方法。这是因为我假设 @collaborators 是一个集合。

--

您需要传递一个 collaborator 对象:

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

由于您使用 .each 循环和 @wiki.users,因此每个 user(我认为是 collaborator)都有 local variable分配给 c 个:

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

由于您是新手,我强烈建议您使用 font-awesome-rails over glyphicon. The main benefit is the fa_icon 帮助器,它允许您使用:

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

尝试遍历 @wiki 的协作者以获得正确的 link。 wiki 的合作者在您的情况下是 wiki 的用户,因为他们是通过合作者关系连接的。所以你只需要做:

<% @wiki.users.each do |collaborator| %>
  <%= link_to "", wiki_collaborator_path(@wiki, collaborator), method: :delete, remote: true, class: "glyphicon glyphicon-remove"  %>
<% end %>