如何链接到父循环内的嵌套路由操作?

时间:2015-04-06 19:38:29

标签: ruby-on-rails ruby ruby-on-rails-4

我试图在索引页面上显示所有内容,但是当我尝试链接到new_story_substory_path时,我得到了未定义的局部变量或方法子目录。

以下是代码:

index.html.erb

<% @stories.each do |story| %>
  <h3><p><%= story.title %></p></h3>
  <p><%= story.plot %></p>

  <% if story.user == current_user %>
    <%= link_to 'Show XXX', story_path(story), class: "btn btn-success" %>
    <%= link_to 'Edit', edit_story_path(story), class: "btn btn-success" %>
    <%= link_to "Delete", story_path(story), method: :delete, data: { confirm: "Are you sure?" }, class: "btn btn-success" %></br>
  <% end %>

  <% story.substories.each do |substory| %>
    <h4><p><%= substory.title %></p></h3>
    <p><%= substory.subplot %></p>

    <% if story.user == current_user %>
      <%= link_to 'Show', story_substory_path(substory.story, substory), class: "btn btn-default" %>
      <%= link_to 'Edit', edit_story_substory_path(substory.story, substory), class: "btn btn-default" %>
      <%= link_to "Delete", story_substory_path(substory.story, substory), method: :delete, data: { confirm: "Are you sure?" }, class: "btn btn-default" %>
    <% end %>
  <% end %>
  <br>

  <% if story.user == current_user %>
    <br>
    <br>
    # this is where I'm getting the error:
    <%= link_to 'New subplot', new_story_substory_path(substory.story, substory), class: "btn btn-warning" %>
    # however if I move this up, inside the second loop, it works perfectly.
    <br>
  <% end %>
<% end %>

<br>

<%= link_to 'New Story', new_story_path, class: "btn btn-danger" %>

这是我的控制器,路线和模型:

class StoriesController < ApplicationController
  before_action :set_story, only: [:show, :edit, :update, :destroy]
  before_action :authenticate_user!, except: [:index, :show]

  def index
    @stories = Story.all
  end

  def show
  end

  def new
    @story = current_user.stories.build
  end

  def edit
  end

  def create
    @story = current_user.stories.build(story_params)

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

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

  def destroy
    @story.destroy
    respond_to do |format|
      format.html { redirect_to stories_url, notice: 'Story was successfully destroyed.' }
      format.json { head :no_content }
    end
  end

  private
    def set_story
      @story = Story.find(params[:id])
    end

    def story_params
      params.require(:story).permit(:title, :plot)
    end
end

Rails.application.routes.draw do

  devise_for :users

  resources :stories do
    resources :substories
  end

  root 'stories#index'

end

class Story < ActiveRecord::Base
    has_many :substories, dependent: :destroy
    belongs_to :user
end

class Substory < ActiveRecord::Base
    belongs_to :story
    belongs_to :user
end

class User < ActiveRecord::Base
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable

  has_many :stories, dependent: :destroy
  has_many :substories, dependent: :destroy
end

我错过了什么?

编辑:

这是变电站的控制器:

class SubstoriesController < ApplicationController
  before_action :set_substory, only: [:show, :edit, :update, :destroy]
  before_action :authenticate_user!
  before_action :set_story

  def index
    @Substories = @story.substories.all
  end

  def show
  end

  def new
    @substory = Substory.new
  end

  def edit
  end

  def create
    @substory = Substory.new(substory_params)
    @substory.user_id = current_user.id
    @substory.story_id = @story.id
    if
      @substory.save
        redirect_to @story
    else
      render 'new'
    end
  end

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

  def destroy
    @substory.destroy
    redirect_to root_path
  end

  private
    def set_story
      @story = Story.find(params[:story_id])
    end

    def set_substory
      @substory = Substory.find(params[:id])
    end

    def substory_params
      params.require(:substory).permit(:title, :subplot)
    end
end

2 个答案:

答案 0 :(得分:0)

我试图将此作为评论,但我需要50个声望点才能这样做。无论如何,这是我的解决方案:

问题是index.html来自Stories Controller。此时,您实际上没有使用任何其他控制器。这是使用ROR的单页应用程序中的常见问题。事情确实如此混乱。

你是对的,你必须在第二个循环上移动你的错误。问题是它会不止一次出现。那是因为有不止一个故事。如果你想避免这种情况,我想说的解决办法就是制作故事#show show.html.erb。点击故事后,它会指向substroy,然后会有一个情节。

答案 1 :(得分:0)

我从评论中得到了答案。

MrYoshi写道:

在产生错误的行:您正在调用子变量,但它只存在于story.substories.each循环中;你可能想要使用 new_story_substory_path(故事)(通往目前已经看过/编辑过的故事的一个替代品的创建页面的路径)

基本上我改变了线形:

<%= link_to 'New subplot', new_story_substory_path(substory.story, substory), class: "btn btn-warning" %>

为:

<%= link_to 'New subplot', new_story_substory_path(story), class: "btn btn-warning" %>

这有效!