为什么我得到ActionView :: Template :: Error:未定义的方法`name'为nil:Heroku上的NilClass,但不是本地的 [英] Why do I get ActionView::Template::Error: undefined method `name' for nil:NilClass on Heroku but not locally

查看:150
本文介绍了为什么我得到ActionView :: Template :: Error:未定义的方法`name'为nil:Heroku上的NilClass,但不是本地的的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个Rails 4应用程序在本地运行SQLite,在Heroku上运行PostgreSQL。



我的PostController的索引操作有问题。我得到了上面的错误,但只在Heroku上。



我已经重新检查了所有代码并运行所有迁移并重新启动了Heroku服务器。我还仔细检查过迁移在本地和Heroku上都是一样的。这个问题似乎与通过Post模型访问用户模型中的数据有关。例如,我试图通过Heroku上的Rails控制台访问其他属性,例如电子邮件,但我得到了相同的未定义方法错误。所以我很确定它与表连接有关。



另外要说明的是,我在生产数据库中有数据



'p>下面是我的PostsController动作:

 类PostsController< ApplicationController 
before_filter:authenticate_user !,除外:[:index::show]

before_action:set_post,only:[:show,:edit,:update,:destroy]

#GET / posts
#GET /posts.json
def index
@posts = Post.all
end
end

我的博文模式:

  class Post< ActiveRecord :: Base 

belongs_to:user
end

我的在用户模型代码:

 类User< ActiveRecord :: Base 

rolify

#包含默认的设计模块。其他可用的是:
#:可确认,:可锁定,:可超时和:omniauthable
devise:database_authenticatable,:可注册,
:可恢复,:可记住,:可跟踪,:validatable,:可确定

belongs_to:资格
has_many:职位

验证:电话,状态:true,格式:{with:/ \ {3} .\d { 3} .\d {4} /,message:必须为555.555.5555格式}
验证:名称,存在:true
验证:电子邮件,存在:true
验证:确认,存在:true

#新功能设置密码,但不知道我们确认控制器中使用的当前密码。
def attempt_set_password(params)
p = {}
p [:password] = params [:password]
p [:password_confirmation] = params [:password_confirmation]
update_attributes( p)
结束

#新函数返回是否设置了密码
def has_no_password?
self.encrypted_pa​​ssword.blank?
结束

#提供访问受保护方法的新函数unless_confirmed
def only_if_unconfirmed
pending_any_confirmation {yield}
结束

def password_required?
#密码是必需的,如果它被设置,但不是新的记录
如果!持久?
false
else
!password.nil? || !password_confirmation.nil?
end
end

end

而我的index.html.erb文件:

 <%@ posts.each do | post | %GT; 
< h2 class ='subheader'><%= link_to post.title,post%>< / h2>由<%= post.user.name%>写入的
< h6> on<%= post.created_at.to_s(:long)%>< / h6>
< div><%= post.body.html_safe%>< / div>
<%如果user_signed_in? %GT;
<%if current_user.has_role? :admin%>
< div><%= link_to'编辑',edit_post_path(post)%>< / div>
< DIV><%=的link_to破坏,岗位,方法:删除数据:{确认:你确定}%GT; < / DIV>
<%end%>
<%end%>
<%end%>
< br>

<%= link_to'New Post',new_post_path%>

我的Heroku日志输出:

  2013-12-19T06:31:13.280899 + 00:00 app [web.1]:2013-12-19 06:31开始GET/ posts为64.114.175.126 13 +0000 
2013-12-19T06:31:13.280899 + 00:00 app [web.1]:2013-12-19 06:31:13 +0000开始GET/ posts为64.114.175.126
2013-12-19T06:31:13.283663 + 00:00 app [web.1]:通过PostsController#index处理HTML
2013-12-19T06:31:13.283663 + 00:00 app [ web.1]:通过PostsController#index处理为HTML
2013-12-19T06:31:13.292344 + 00:00 app [web.1]:在布局/应用程序中呈现posts / index.html.erb(6.9 ms)
2013-12-19T06:31:13.292553 + 00:00 app [web.1]:在9ms内完成500次内部服务器错误
2013-12-19T06:31:13.292344 + 00:00应用程序[web.1]:在布局/应用程序中呈现posts / index.html.erb(6.9ms)
2013-12-19T06:31:13.292553 + 00:00应用程序[web.1]:已完成500内部9ms内的服务器错误
2013-12-19T06:31:13.295581 + 00:00 app [web.1]:
2013-12 -19T06:31:13.295581 + 00:00 app [web.1]:6:< div><%= post.body.html_safe%>< / div>
2013-12-19T06:31:13.295581 + 00:00 app [web.1]:3:<%@ posts.each do | post | %GT;
2013-12-19T06:31:13.295581 + 00:00 app [web.1]:7:<%if user_signed_in? %GT;
2013-12-19T06:31:13.295581 + 00:00 app [web.1]:2:
2013-12-19T06:31:13.295581 + 00:00 app [web.1]: 4:< h2 class ='subheader'><%= link_to post.title,post%>< / h2>
2013-12-19T06:31:13.295581 + 00:00 app [web.1]:ActionView :: Template :: Error(nil:NilClass的未定义方法`name'):
2013-12 -19T06:31:13.295581 + 00:00 app [web.1]:5:< h6>由<%= post.user.name%>写入< on<%= post.created_at.to_s(:long)%>< / h6>
2013-12-19T06:31:13.295778 + 00:00应用程式[web.1]:应用/视图/帖/ index.html.erb:3:`_app_views_posts_index_html_erb__338969566965495969_70155247178440'
2013-12- 19T06:31:13.295778 + 00:00 app [web.1]:2:
2013-12-19T06:31:13.295778 + 00:00 app [web.1]:
2013-12- 19T06:31:13.295778 + 00:00 app [web.1]:ActionView :: Template :: Error(nil:NilClass的未定义方法名称):
2013-12-19T06:31:13.295778 + 00 :00 app [web.1]:
2013-12-19T06:31:13.295778 + 00:00 app [web.1]:3:<%@ posts.each do | post | %GT;
2013-12-19T06:31:13.295778 + 00:00 app [web.1]:
2013-12-19T06:31:13.295581 + 00:00 app [web.1]:8: <%如果current_user.has_role? :admin%>
2013-12-19T06:31:13.295581 + 00:00应用程式[web.1]:应用/视图/帖/ index.html.erb:5:在`块_app_views_posts_index_html_erb__338969566965495969_70155247178440'
2013- 12-19T06:31:13.295778 + 00:00应用程式[web.1]:5:其中H6>%= post.user.name%GT;以<写的; on<%= post.created_at.to_s(:long)%>< / h6>
2013-12-19T06:31:13.295778 + 00:00 app [web.1]:6:< div><%= post.body.html_safe%>< / div>
2013-12-19T06:31:13.295947 + 00:00 app [web.1]:7:<%if user_signed_in? %GT;
2013-12-19T06:31:13.295947 + 00:00 app [web.1]:8:<%if current_user.has_role? :admin%>
2013-12-19T06:31:13.295947 + 00:00应用程式[web.1]:应用/视图/帖/ index.html.erb:5:在`块_app_views_posts_index_html_erb__338969566965495969_70155247178440'
2013- 12-19T06:31:13.295947 + 00:00应用程式[web.1]:应用/视图/帖/ index.html.erb:3:`_app_views_posts_index_html_erb__338969566965495969_70155247178440'
2013-12-19T06:31:13.295778+ 00:00 app [web.1]:4:< h2 class ='subheader'><%= link_to post.title,post%>< / h2>
2013-12-19T06:31:13.295947 + 00:00 app [web.1]:
2013-12-19T06:31:13.295947 + 00:00 app [web.1]:
2013-12-19T06:31:13.303637 + 00:00 heroku [router]:at = info method = GET path = / posts host = www.kettlecreekventure.com fwd =64.114.175.126dyno = web.1 connect = 8ms service = 25ms status = 500 bytes = 1266
2013-12-19T06:31:14.630725 + 00:00 heroku [router]:at = info method = GET path = / favicon.ico host = www.kettlecreekventure .com fwd =64.114.175.126dyno = web.1 connect = 1ms service = 4ms status = 200 bytes = 0
2013-12-19T06:31:22.445573 + 00:00 heroku [run.7634]:进程退出,状态为0
2013-12-19T06:31:22.459444 + 00:00 heroku [run.7634]:状态从上升到完成

同样,代码在我的本地机器上完美工作,但在部署到Heroku后发生上述错误时失败。当应用程序尝试引用post.user.name时,index.html.erb文件中出现错误。我正在试图弄清楚自己的头发。
如果有人能看到我的问题在哪里,我将不胜感激。根据你的更新,我会提出这样的建议:每次你删除一个有帖子的用户和然后尝试列出他们的帖子<%= post.user.name%> 将返回nil,因为此帖子不再有用户参考。您可以使用

  has_many:posts,dependent::destroy 

,正如我上面所建议的那样,或者您添加一些功能来删除用户,以防止在查看他们的帖子时发生错误。一些选择是:

删除用户时,您可以删除用户表中该行的所有名称和ID,这将允许您拥有<%= post.user.name%> 返回一个值。



当用户被删除后,您可以删除其用户表信息中的所有内容,并添加用户删除后的用户类似于Tumblr在用户停用帐户和他们的名字出现在其他一些Tumblr的帖子中。

您可以在数据库中创建一个名为用户删除的用户,并让该用户继承删除用户的每篇文章。在用户控制器中添加删除操作中的内容,将其帖子中的user_id字段更改为用户删除的帐户。



最后,您可以检查post.user是否返回一个值,如果不是只打印用户不再存在于系统中这样的内容,那么

当然,如果你想让用户被删除但仍然保留他们的帖子,这一切都是依赖的。如果这不仅仅是一个课程项目,或者你只是为了学习Rails而做的事情,那肯定是一个可能的情况。希望这可以帮助。这当然让我在允许用户删除他们的个人资料,而不必到位后,他们收拾东西思考的陷阱。


I have a Rails 4 app running SQLite locally and PostgreSQL on Heroku.

I am having problems with the index action of my PostController. I get the above error, but only on Heroku.

I have double checked all the code and run all migrations and restarted the Heroku server. I have also double checked that the migrations are identical both locally and on Heroku. The issue seems to be specifically related to accessing data in the User model through the Post model. For instance, I've tried to access other attributes such as email through the rails console on Heroku but I get the same undefined method error. So I'm pretty sure it has something to do with the table join.

Also to clarify, I do have data in the production DB

Here's my PostsController action:

class PostsController < ApplicationController
  before_filter :authenticate_user!, except: [:index, :show]

  before_action :set_post, only: [:show, :edit, :update, :destroy]

  # GET /posts
  # GET /posts.json
  def index
    @posts = Post.all
  end
end

My Post model:

class Post < ActiveRecord::Base

    belongs_to :user
end

My code in the User model:

class User < ActiveRecord::Base

  rolify

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

  belongs_to :qualification
  has_many :posts

  validates :phone, presence: true, format: { with: /\d{3}.\d{3}.\d{4}/, message: "Must be in 555.555.5555 format" }
  validates :name, presence: true
  validates :email, presence: true
  validates :acknowledgement, presence: true

  # new function to set the password without knowing the current password used in our confirmation controller. 
  def attempt_set_password(params)
    p = {}
    p[:password] = params[:password]
    p[:password_confirmation] = params[:password_confirmation]
    update_attributes(p)
  end

  # new function to return whether a password has been set
  def has_no_password?
    self.encrypted_password.blank?
  end

  # new function to provide access to protected method unless_confirmed
  def only_if_unconfirmed
    pending_any_confirmation {yield}
  end

  def password_required?
  # Password is required if it is being set, but not for new records
  if !persisted? 
    false
  else
    !password.nil? || !password_confirmation.nil?
  end
end

end

And my index.html.erb file:

<% @posts.each do |post| %>
<h2 class='subheader'><%= link_to post.title, post %></h2>
<h6>written by <%= post.user.name %> on <%= post.created_at.to_s(:long) %></h6>
<div><%= post.body.html_safe %></div>
<% if user_signed_in? %>
<% if current_user.has_role? :admin %>
<div><%= link_to 'Edit', edit_post_path(post) %></div>
<div><%= link_to 'Destroy', post, method: :delete, data: { confirm: 'Are you sure?' } %>  </div>
<% end %>
<% end %>
<% end %>
<br>

<%= link_to 'New Post', new_post_path %>

The output from my Heroku log:

2013-12-19T06:31:13.280899+00:00 app[web.1]: Started GET "/posts" for 64.114.175.126 at     2013-12-19 06:31:13 +0000
2013-12-19T06:31:13.280899+00:00 app[web.1]: Started GET "/posts" for 64.114.175.126 at  2013-12-19 06:31:13 +0000
2013-12-19T06:31:13.283663+00:00 app[web.1]: Processing by PostsController#index as HTML
2013-12-19T06:31:13.283663+00:00 app[web.1]: Processing by PostsController#index as HTML
2013-12-19T06:31:13.292344+00:00 app[web.1]:   Rendered posts/index.html.erb within layouts/application (6.9ms)
2013-12-19T06:31:13.292553+00:00 app[web.1]: Completed 500 Internal Server Error in 9ms
2013-12-19T06:31:13.292344+00:00 app[web.1]:   Rendered posts/index.html.erb within layouts/application (6.9ms)
2013-12-19T06:31:13.292553+00:00 app[web.1]: Completed 500 Internal Server Error in 9ms
2013-12-19T06:31:13.295581+00:00 app[web.1]:
2013-12-19T06:31:13.295581+00:00 app[web.1]:     6: <div><%= post.body.html_safe %></div>
2013-12-19T06:31:13.295581+00:00 app[web.1]:     3: <% @posts.each do |post| %>
2013-12-19T06:31:13.295581+00:00 app[web.1]:     7: <% if user_signed_in? %>
2013-12-19T06:31:13.295581+00:00 app[web.1]:     2:
2013-12-19T06:31:13.295581+00:00 app[web.1]:     4: <h2 class='subheader'><%= link_to post.title, post %></h2>
2013-12-19T06:31:13.295581+00:00 app[web.1]: ActionView::Template::Error (undefined method `name' for nil:NilClass):
2013-12-19T06:31:13.295581+00:00 app[web.1]:     5: <h6>written by <%= post.user.name %> on <%= post.created_at.to_s(:long) %></h6>
2013-12-19T06:31:13.295778+00:00 app[web.1]:   app/views/posts/index.html.erb:3:in `_app_views_posts_index_html_erb__338969566965495969_70155247178440'
2013-12-19T06:31:13.295778+00:00 app[web.1]:     2:
2013-12-19T06:31:13.295778+00:00 app[web.1]:
2013-12-19T06:31:13.295778+00:00 app[web.1]: ActionView::Template::Error (undefined method `name' for nil:NilClass):
2013-12-19T06:31:13.295778+00:00 app[web.1]:
2013-12-19T06:31:13.295778+00:00 app[web.1]:     3: <% @posts.each do |post| %>
2013-12-19T06:31:13.295778+00:00 app[web.1]:
2013-12-19T06:31:13.295581+00:00 app[web.1]:     8: <% if current_user.has_role? :admin %>
2013-12-19T06:31:13.295581+00:00 app[web.1]:   app/views/posts/index.html.erb:5:in `block in _app_views_posts_index_html_erb__338969566965495969_70155247178440'
2013-12-19T06:31:13.295778+00:00 app[web.1]:     5: <h6>written by <%= post.user.name %> on <%= post.created_at.to_s(:long) %></h6>
2013-12-19T06:31:13.295778+00:00 app[web.1]:     6: <div><%= post.body.html_safe %></div>
2013-12-19T06:31:13.295947+00:00 app[web.1]:     7: <% if user_signed_in? %>
2013-12-19T06:31:13.295947+00:00 app[web.1]:     8: <% if current_user.has_role? :admin %>
2013-12-19T06:31:13.295947+00:00 app[web.1]:   app/views/posts/index.html.erb:5:in `block in _app_views_posts_index_html_erb__338969566965495969_70155247178440'
2013-12-19T06:31:13.295947+00:00 app[web.1]:   app/views/posts/index.html.erb:3:in `_app_views_posts_index_html_erb__338969566965495969_70155247178440'
2013-12-19T06:31:13.295778+00:00 app[web.1]:     4: <h2 class='subheader'><%= link_to post.title, post %></h2>
2013-12-19T06:31:13.295947+00:00 app[web.1]:
2013-12-19T06:31:13.295947+00:00 app[web.1]:
2013-12-19T06:31:13.303637+00:00 heroku[router]: at=info method=GET path=/posts host=www.kettlecreekventure.com fwd="64.114.175.126" dyno=web.1 connect=8ms service=25ms status=500 bytes=1266
2013-12-19T06:31:14.630725+00:00 heroku[router]: at=info method=GET path=/favicon.ico host=www.kettlecreekventure.com fwd="64.114.175.126" dyno=web.1 connect=1ms service=4ms status=200 bytes=0
2013-12-19T06:31:22.445573+00:00 heroku[run.7634]: Process exited with status 0
2013-12-19T06:31:22.459444+00:00 heroku[run.7634]: State changed from up to complete

Again, the code works perfectly on my local machine but fails with the above error after I have deployed to Heroku. There error is in the index.html.erb file when the app tries to reference post.user.name. I'm pulling my hair out trying to figure it out. I would appreciate if anyone can see where my problem is. What am I doing wrong?

解决方案

According to your update I will propose this: Every time you delete a user who has posts and then try to list their posts <%= post.user.name %> will return nil because this post no longer has a user to refer to. You can either use the

has_many :posts, dependent: :destroy 

in the User model as I suggested above, or you add some functionality to the deleting of users to prevent errors when trying to view their posts. Some choices are:

When a user is deleted you can just delete everything but their name and id in that row of the user table, that will allow you to have <%= post.user.name %> return a value.

When a user is deleted you can delete everything in their User table info and add "-user-deleted" after it kind of like what Tumblr does when a user deactivates their account and their name shows up in a post on some other Tumblr.

You can create a User in the DB called "user-deleted" and have that user inherit every post from a user who is deleted. In the User controller add something in your delete action to change the user_id field in their posts to the "user-deleted" account.

Or finally you could just check to see if post.user returns a value, and if not just print something like "The user no longer exists in the system"

This is all dependent of course on if you even want to allow users to be deleted but still keep their posts. That's certainly a likely case if this is more than just a class project or something you are doing just to learn Rails. Hope this helps. It certainly got me thinking about the pitfalls in allowing users to delete their profiles without having something in place to clean up after them.

这篇关于为什么我得到ActionView :: Template :: Error:未定义的方法`name'为nil:Heroku上的NilClass,但不是本地的的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆