无法 'link_to' 代码中的特定路由,但可以通过手动将它们输入浏览器来访问它们

Not able to 'link_to' specific routes in code, but can access them by manually entering them into the browser

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

我已经设置了一个名为 Captable 的嵌套资源模型。它 belongs_to 一家公司。

如果我导航到某个视图:例如 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>

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

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>

下面是一些代码片段:

routes.rb

Rails.application.routes.draw do

  devise_for :users
  get 'dashboard/index'

  root 'companies#index'

  resources :companies do
    resources :shareholders
    resources :captables
  end

end

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

schema.rb

这是 table 的架构:

  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

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

link 应为:

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