【问题标题】:Rails 4 - Toggle Boolean to false on clickRails 4 - 单击时将布尔值切换为 false
【发布时间】:2015-06-16 20:12:27
【问题描述】:

我正在尝试使用 Rails 4 构建应用程序。

该应用有 3 个模型 - 一个用于 Project,一个用于 Scope,一个用于 Finalise。

Finalise 属于范围。范围属于项目。 Project 接受 Scope(和 Finalise)的嵌套属性,Scope 接受 Finalise 的嵌套属性。

在我的定稿模型中,我有一个用于 :draft 的布尔属性。如果草稿为真,那么我想在项目显示页面上包含一个链接,以便在草稿完成时将 :draft 切换为假。

一位 SO 成员在附件中给了我一些建议(我试图遵循这些建议,但没有用于切换布尔属性)。

在我的项目控制器中,我有:

  def new
    #authorise @project
    @project = Project.new
    @project.scope = Scope.new
    @project.scope.finalise = Finalise.new

  end

在我的范围控制器中,我有;

 def new
    @scope = Scope.new
    @scope.finalises.build
  end

在我的 finalizes 控制器中,我有一个方法(由另一个 SO 用户建议):

def toggle_draft
    @finalise = Finalise.find(params[:id])
    @finalise.draft = true
    @finalise.save
    redirect_to project_path(@project)
  end

最终确定的路线有:

 resources :finalises do
   patch '/toggle-draft', to: 'finalises#toggle_draft', as: 'toggle_draft'
end

finalize部分节目(已纳入项目节目)有:

    <% if @project.scope.finalise.draft == true %>
           <div class="finalise"> <%= link_to 'Finalise this draft', 
 finalise_toggle_draft_path(:id => @finalise.id),  :remote => true, method: :patch %></div>

    <% end %>

当我尝试这个时,我收到一条错误消息:

nil:NilClass 的未定义方法 `id'

Gabriel(下)建议我可能需要通过关联进行链接(所以@project.scope.finalise.id)。我已经尝试过这个公式和@project.scope.finalise_id。这些都不起作用。

当我尝试时:

<% if @project.scope.finalise.draft == true %>
    <div class="finalise"> <%= link_to 'Finalise this draft',
                                       finalise_toggle_draft_path(:id => @project.scope.finalise.id),  :remote => true, method: :patch %></div>

<% end %>

我收到一条错误消息: 没有路线匹配 {:action=>"toggle_draft", :controller=>"finalises", :id=>1} 缺少必需的键:[:finalise_id]

当我尝试时:

我收到一条错误消息:

<% if @project.scope.finalise.draft == true %>
    <div class="finalise"> <%= link_to 'Finalise this draft',
                                       finalise_toggle_draft_path(:id => @project.scope.finalise.id), :action => 'toggle-draft',   :remote => true, method: :patch %></div>

<% end %>

没有路由匹配 {:action=>"toggle_draft", :controller=>"finalises", :id=>1} 缺少必需的键:[:finalise_id]

当我尝试时:

我收到此错误:

<% if @project.scope.finalise.draft == true %>
    <div class="finalise"> <%= link_to 'Finalise this draft',
                                       controller: "finalises", action: "toggle_draft",
                                       finalise_id: @finalise_id,
                                       :remote => true,
                                       method: :patch %>
    </div>

<% end %>

没有路线匹配 {:action=>"toggle_draft", :controller=>"finalises", :id=>"53", :finalise_id=>nil, :method=>:patch}

谢谢

【问题讨论】:

  • link_to 使用“GET”,因此您需要指定方法,例如link_to "完成这个草稿", toggle_draft_path(@finalise_id), 方法: :patch
  • 感谢 Margo,我在该 link_to 段的末尾添加了 'method: :patch',但我仍然收到一个路由错误消息:没有路由匹配 [GET] "/toggle-draft"
  • 如果你运行rake routes,你可能会看到路由被命名为finalise_toggle_draft,所以你需要在partial中使用finalise_toggle_draft_path
  • 非常感谢您的帮助。我现在收到此错误:No route matches {:action=>"toggle_draft", :controller=>"finalises", :id=>nil} missing required keys: [:finalise_id]
  • 你传过id了吗,finalise_toggle_draft_path(@finalise_id)

标签: ruby-on-rails


【解决方案1】:

在项目控制器中

def show
  @project = Project.find(params[:id])
end

在项目显示视图中

<%= link_to 'Finalise draft', finalise_toggle_draft_path(@project.scope.finalise.id), method: :patch

您应该能够使用命名路由并传递您可以从@project 获得的finalize id。您必须小心如何在 finalises#toggle_draft 方法中获得 finalize 模型,检查参数的命名方式,可能是 finalise_id,而不是 id。最好阅读嵌套资源以及如何在控制器之间传递变量。

【讨论】:

  • 嗨,Margo,我已经尝试将 id 作为“@project.scope.finalise.id”和“@project.scope.finalise_id”,但在这两种情况下,我都会收到一条错误消息: 在没有 ID 的情况下找不到 Finalize
【解决方案2】:

这就是最终的工作(使用 Margo 的指导):

完成部分:

<div class="finalise">
  <%= link_to 'Finalise draft', finalise_toggle_draft_path(projectid: @project.id, id: @project.scope.finalise.id, finalise_id: @project.scope.finalise.id), method: :patch %>
</div>

Finalises_controller

  def toggle_draft
    @finalise = Finalise.find(params[:id])
    @finalise.draft = false
    @finalise.finalised = Time.now
    @finalise.save
    redirect_to project_path(Project.find(params[:projectid]))

【讨论】:

  • 你能正常工作真是太好了。我没有给你完整的解决方案,因为当你弄清楚如何调试和解决问题时,你将能够更快地解决未来的问题。在部分中,您只需执行 link_to “Finalise Draft”,finalise_toggle_draft_path(@project.scope.finalise.id)。然后在 toggle_draft 方法中,@finalise = Finalise.find(params[:finalise_id])。在控制台中运行 rake 路由,您将看到路由中预期的参数。由于您需要将项目实例重定向到,因此在 params 数组中传递它是正确的。
  • 祝你的项目好运!
  • 非常感谢玛戈。我非常感谢您的帮助
  • 我尝试按照您的建议更改链接和 toggle_draft 方法,但现在我在尝试此操作时收到错误消息:找不到没有 ID 的项目
  • 我猜您在尝试重定向到 project_path 时遇到了错误。您是否将 project_id 作为参数传递?尽管您不需要,您可以从 finalize 实例中获取它。重定向到项目路径(@finalise.scope.project.id)。您需要阅读关联的工作原理并使用控制台进行练习。
【解决方案3】:

@finalise_id未定义...您可以通过关系@project.scope.finalise.id获取id

<% if @project.scope.finalise.draft == true %>
   <div class="finalise"> <%= link_to 'Finalise this draft', finalise_toggle_draft_path(id: @project.scope.finalise.id), method: :patch  %></div>
<% end %>

【讨论】:

    猜你喜欢
    • 2017-08-05
    • 2021-09-02
    • 1970-01-01
    • 1970-01-01
    • 2013-09-13
    • 2011-08-26
    • 1970-01-01
    • 1970-01-01
    • 2015-09-22
    相关资源
    最近更新 更多