我在这里遇到了一些麻烦 - 我有一个项目模型&控制器以及版本模型和控制器。用户创建项目的版本,在项目配置文件中,我有一个指向版本索引页面的链接,该页面应该只显示该特定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 %>
答案 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