我项目中的Rails 4路由(或丢失ID)错误&版本协会

时间:2014-04-13 22:00:47

标签: ruby-on-rails ruby-on-rails-4 routing rails-routing link-to

我在这里遇到了一些麻烦 - 我有一个项目模型&控制器以及版本模型和控制器。用户创建项目的版本,在项目配置文件中,我有一个指向版本索引页面的链接,该页面应该只显示该特定project_id的版本。该页面的URL应为" projects / [project_id] / versions" ...但我收到以下错误:

Showing /Users/user/Documents/clones/collab/app/views/versions/index.html.erb where line #46 raised:

-------
undefined method `id' for nil:NilClass
Extracted source (around line #46):

     <ul class="nav nav-pills"> 
       <li class="active"><%= link_to "Current State", @project %></li>
       <li>
         <%= link_to "Version History", project_versions_path(@project.id) %>
       </li>
       <li><a href="#"><span class="badge pull-right">12</span>Collaborators</a></li>  
       <li><a href="#"><span class="badge pull-right">6</span>Issues</a></li>
-------

我想知道我是否可能错误地构建了控制器,因为从技术上来说,它是一个&#39;版本的索引列表&#39;对于特定的项目配置文件(而不仅仅是所有项目的站点范围的版本索引)。我也意识到我对显示页面上的导航列表有一些重复,可以移动到部分...但我只是想让代码现在正常工作...感谢任何帮助解决这个问题......

的routes.rb

  resources :users
  resources :sessions, only: [:new, :create, :destroy]

  resources :projects do
    resources :versions
  end

  # get "static_pages/home"
  # get "static_pages/help"
  # get "static_pages/about"
  #The original routes above map to...
  root  'static_pages#home'
  match '/signup',  to: 'users#new',            via: 'get'
  match '/signin',  to: 'sessions#new',         via: 'get'
  match '/signout', to: 'sessions#destroy',     via: 'delete'
  match '/help',    to: 'static_pages#help',    via: 'get'
  match '/about',   to: 'static_pages#about',   via: 'get'
  match '/contact', to: 'static_pages#contact', via: 'get'

项目模型:

class Project < ActiveRecord::Base
  has_many :users
  has_many :versions, dependent: :destroy
  validates :title, presence: true, length: { maximum: 100 }
  validates :background, presence: true
  validates :user_id, presence: true

  default_scope -> { order('created_at DESC') }
end

PROJECTS CONTROLLER:

class ProjectsController < ApplicationController
  before_filter :signed_in_user, only: [:create, :new, :edit, :update]

  def new
    @project = Project.new
  end

  def show
     @project = Project.find(params[:id])
     @user = User.where(:id => @project.user_id).first
  end

  def index
    @projects = Project.paginate(page: params[:page])
  end

  def create
    @project = current_user.projects.build(project_params)
    if @project.save
      flash[:success] = "Welcome to your new project."
      redirect_to @project
    else
      render 'new'
    end
  end

  def edit

  end

  def update
    @project = Project.find(params[:id])
    if @project.update_attributes(params[:project])
      flash[:success] = "Project Created"
      redirect_to @project
    else
      render 'edit'
    end
  end

  def destroy
    User.find(params[:id]).destroy
    flash[:success] = "Project destroyed"
    redirect_to users_path
  end

  private

    def project_params
      params.require(:project).permit(:title, :background)
    end

end

PROJECTS SHOW(PROJECT PROFILE):

<% provide(:title, @project.title) %>

<div class="row-fluid">
  <section class="no-pad col-md-9">

    <div class="row-fluid">   
      <div class="no-pad col-md-10"> 
        <h1><%= @project.title %></h1>
        <span class="timestamp"><span class="glyphicon glyphicon-time"></span> Created <%= time_ago_in_words(@project.created_at) %> ago by <%= @project.user_id %></span>
        <p><%= @project.background %></p>

      </div>
      <div class="col-md-2">
        <%= link_to "#", :class => "pull-right" do %>
          <%= image_tag("lock.png", alt: "private info") %>
        <% end %><br clear="all">
        <span class="timestamp pull-right">private</span>
      </div> 
    </div><br clear="all">

    <div class="row-fluid">
      <ul class="nav nav-pills"> 
        <li class="active"><%= link_to "Current State", @project %></li>
        <li>
          <%= link_to "Version History", project_versions_path(@project.id) %>
        </li>
        <li><a href="#"><span class="badge pull-right">12</span>Collaborators</a></li>  
        <li><a href="#"><span class="badge pull-right">6</span>Issues</a></li>
        <li><a href="#"><span class="badge pull-right"></span>Project Buzz</a></li>
      </ul><br clear="all">
    </div>

    <div class="row-fluid">

      <div class="no-pad col-md-6">
        <h4>File Attachment</h4>
        <div class="bs-callout bs-callout-success">
          <%= link_to "download" do %>
            <%= image_tag("icon.png", alt: "file") %>
          <% end %><br clear="all">
        </div>
      </div>

      <!-- LATEST PROJECT VERSIONS -->
      <div class="col-md-6">  
        <h4>Latest Versions</h4>

        <% @project.versions.first(5).each do |version| %> 

          <%= link_to project_version_path(@project, version) do %>
            <h6><%= version.title %></h6>
          <% end %>

        <% end %>
      </div>
      <!-- END OF PROJECT VERSIONS -->

    </div>

VERSIONS MODEL:

class Version < ActiveRecord::Base
  belongs_to :project
  validates :title, presence: true, length: { maximum: 140 }

  default_scope -> { order('created_at DESC') }
end

VERSIONS CONTROLLER:

class VersionsController < ApplicationController
  def new
    @version = Version.new
  end

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

  def index
    @versions = Version.paginate(page: params[:page])
  end

  def create
    @project = Project.find(params[:project_id])
    @version = @project.versions.create(version_params)
    if @version.save
      flash[:success] = "You've successfully added a version to this branch..."
      redirect_to project_path(@project)
    else
      render 'new'
    end
  end

  def edit

  end

  def update

  end

  def destroy

  end

  private

    def version_params
      params.require(:version).permit(:title)
    end
end

VERSIONS INDEX(Url将是&#34; projects / [project_id] /版本&#34;

<% provide(:title, @versions ) %>

<div class="row-fluid">
  <section class="no-pad col-md-9">


    <div class="row-fluid">
      <ul class="nav nav-pills"> 
        <li><%= link_to "Current State", @project %></li>
        <li class="active">
          <%= link_to "Version History", project_versions_path(@project.id) %>
        </li>
        <li><a href="#"><span class="badge pull-right">12</span>Collaborators</a></li>  
        <li><a href="#"><span class="badge pull-right">6</span>Issues</a></li>
        <li><a href="#"><span class="badge pull-right"></span>Project Buzz</a></li>
      </ul><br clear="all">
    </div>

    <h4>Version History</h4>

    <%= will_paginate %>

    <ul class="versions">
      <% @versions.each do |version| %>
        <%= render version %>
      <% end %>
    </ul>

    <!-- CAN REFACTOR TO BELOW FOR CLEANER CODE
    <ul class="versions">
      <%= render @versions %>
    </ul>
    -->

    <%= will_paginate %>

1 个答案:

答案 0 :(得分:1)

app/views/versions/index.html.erb的观点正在寻找@project.id,但@project尚未定义。

您需要在@project操作中为index设置值。我建议将其重构为before_action调用,以便稍微整理一下控制器:

class VersionsController < ApplicationController
  # Also add other actions that need for @project to be set (or leave out the `only`
  # option for ALL actions, which almost certainly applies to your situation with a nested
  # resource like this)
  before_action :find_project, only: [:index, :show, :create]

    def show
      @version = Version.find(params[:id])
    end

    def index
      @versions = Version.paginate(page: params[:page])
    end

    def create
      @version = @project.versions.create(version_params)
      if @version.save
        flash[:success] = "You've successfully added a version to this branch..."
        redirect_to project_path(@project)
      else
        render 'new'
      end
    end

  private

    def find_project
      @project = Project.find(params[:project_id])
    end

    #...
end