首页 > 解决方案 > 无法在代码中“链接到”特定路线,但可以通过手动将它们输入浏览器来访问它们

问题描述

我对 Rails 比较陌生,遇到了一个我似乎无法解决的问题。

我已经设置了一个名为Captable. 它属于一家公司。

如果我导航到某个视图:例如http://localhost:3000/companies/9/captables/1- 一切都很好。我看到了正确的数据。

我有 2 个我似乎无法解决的核心问题,我认为这与命名约定或路由有关。

首先,当我尝试访问时http://localhost:3000/companies/9/captables/new- 我收到以下错误。

NoMethodError in Captables#new
Showing /Users/jamespember/calmcap/app/views/captables/_form.html.erb where line #2 raised:

undefined method `captables_path' for #<#<Class:0x00007f8a08edebc8>:0x00007f8a0984bfa8>
Extracted source (around line #2):
1
2
3
4
5
6


<%= form_with(model: @captable, local: true) do |form| %>

  <% if @captable.errors.any? %>
    <div id="error_explanation">
      <h2>

company_captables_path其次 - 如果我尝试使用以下链接从页面链接到链接/companies/,我会收到以下错误。

View Cap Table: <%= link_to(@company.company_captables_path) %>

错误:

 Showing /Users/jamespember/calmcap/app/views/companies/show.html.erb where line #30 raised:

undefined method `company_captables_path' for #<Company:0x00007f8a046a6630>

以下是一些代码片段:

路线.rb

Rails.application.routes.draw do

  devise_for :users
  get 'dashboard/index'

  root 'companies#index'

  resources :companies do
    resources :shareholders
    resources :captables
  end

end

可捕获的.rb

class Captable < ApplicationRecord
  belongs_to :company
end

captables_controller.rb

class CaptablesController < ApplicationController
  before_action :set_captable, only: [:show, :edit, :update, :destroy]

  def index
    @captables = Captable.all 
  end

  def show
    @captable = Captable.find(params[:id])
  end

  def new
    @captable = Captable.new
  end

  def edit
  end

  def create
    @captable = Captable.new(captable_params)

    respond_to do |format|
      if @captable.save
        format.html { redirect_to @captable, notice: 'Captable was successfully created.' }
        format.json { render :show, status: :created, location: @captable }
      else
        format.html { render :new }
        format.json { render json: @captable.errors, status: :unprocessable_entity }
      end
    end
  end

  def update
    respond_to do |format|
      if @captable.update(captable_params)
        format.html { redirect_to @captable, notice: 'Captable was successfully updated.' }
        format.json { render :show, status: :ok, location: @captable }
      else
        format.html { render :edit }
        format.json { render json: @captable.errors, status: :unprocessable_entity }
      end
    end
  end

  def destroy
    @captable.destroy
    respond_to do |format|
      format.html { redirect_to captables_url, notice: 'Captable was successfully destroyed.' }
      format.json { head :no_content }
    end
  end

  private
    def set_captable
      @captable = Captable.find(params[:id])
    end

    def captable_params
      params.require(:captable).permit(:version, :name, :company_id)
    end
end

captables/show.html.erb

<p id="notice"><%= notice %></p>

<p>
  <strong>Version:</strong>
  <%= @captable.version %>
</p>

<p>
  <strong>Name:</strong>
  <%= @captable.name %>
</p>

<p>
  <strong>Company:</strong>
  <%= @captable.company_id %>
</p>

captables/_form.html.erb - 编辑更新

<%= form_with(model: [@company, @captable], local: true) do |form| %>

  <% if @captable.errors.any? %>
    <div id="error_explanation">
      <h2>
        <%= pluralize(@captable.errors.count, "error") %> prohibited
        this article from being saved:
      </h2>
      <ul>
        <% @captable.errors.full_messages.each do |msg| %>
          <li><%= msg %></li>
        <% end %>
      </ul>
    </div>
  <% end %>

  <p>
    <%= form.submit %>
  </p>

<% end %>

架构.rb

这是表的架构:

  create_table "captables", force: :cascade do |t|
    t.integer "version"
    t.text "name"
    t.integer "company_id"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
  end

最后附上我的截图rails routes

在此处输入图像描述

尝试访问时出错/companies/:id/captables/new

在此处输入图像描述

标签: ruby-on-railsrails-routing

解决方案


rails 路由辅助方法被添加到视图上下文和控制器中 - 而不是模型。

该链接应为:

<%= link_to("Link text", company_captables_path(@company)) %>

这是对以下内容的隐式调用:

<%= link_to("Link text", self.company_captables_path(@company)) %>

self作为视图上下文。

在为嵌套路由创建表单时,您应该传递一个数组:

<%= form_with(model: [@company, @captable], local: true) do |form| %>
   # ...
<% end %>

您还应该从关联创建新实例:

class CaptablesController < ApplicationController
  before_action :set_company
  before_action :set_captable, only: [:show, :edit, :update, :destroy]

  # GET /companies/:company_id/captables/new
  def new
    @captable = @company.captables.new
  end

  # POST /companies/:company_id/captables
  # POST /companies/:company_id/captables.json
  def create
    @captable = @company.captables.new(captable_params)

    respond_to do |format|
      if @captable.save
        format.html { redirect_to @captable, notice: 'Captable was successfully created.' }
        format.json { render :show, status: :created, location: @captable }
      else
        format.html { render :new }
        format.json { render json: @captable.errors, status: :unprocessable_entity }
      end
    end
  end

  private
    def set_company
      @company = Company.find(params[:company_id])
    end

    # ...
end

推荐阅读