【问题标题】:Rails: Added validation and now gettng error: undefined method `model_name' for NilClass:ClassRails:添加了验证,现在出现错误:NilClass:Class 的未定义方法“model_name”
【发布时间】:2011-11-28 05:19:56
【问题描述】:

我正在构建一个带投票功能的应用程序(帖子有很多票,用户有很多票)。当我没有限制每个用户的投票数时它可以工作,但是在添加验证后,当我尝试对同一用户之前投票的帖子进行投票时,它会出现以下错误:

>undefined method `model_name' for NilClass:Class

>Extracted source (around line #28): 

>25: <% end %>  
>26:     
>27: <table class="posts" summary="User posts">  
>28:    <%= render @posts %>  
>29: </table>  

>Trace:
>app/views/posts/index.html.erb:28:in `_app_views_posts_index_html_erb__978098650233580665_2485618500'
>app/controllers/votes_controller.rb:23:in `create'

它在为用户之前没有投票过的帖子投票时起作用。当用户已经为帖子投票时,如何让 rails 闪现错误,然后重定向而没有错误?我确定我只是错过了一些明显的东西。当我尝试通过 rails 控制台添加投票时,验证工作(即,如果该用户已经投票,rails 不会将新投票添加到数据库中)。谢谢 -

vote.rb中的相关代码:

class Vote < ActiveRecord::Base
  attr_accessible :user_id, :post_id
  validate :only_one_user_per_post

  belongs_to :user
  belongs_to :post, :counter_cache => true

private
  def only_one_user_per_post
    if Vote.where("user_id = ? AND post_id = ?", self.user_id, self.post_id).all.any?
      errors.add(:user_id, "Can only post once per post!")
    end
  end
end

从 VotesController.rb 创建

 def create
    @vote = Vote.new(params[:vote])
    post = params[:vote][:post_id]
    uid = params[:vote][:user_id] 
    if @vote.save
      flash[:success] = "You voted for the article"
      redirect_to root_path
   else
      flash[:failure] = "You did not vote"
      render 'posts/index'
    end

来自 index.html.erb 的相关代码:

<% flash.each do |key, value| %>
    <div class="flash <%= key %>"><%= value %></div>
<% end %>

<table class="posts" summary="User posts">
    <%= render @posts %>
</table>

这是来自 _post.html.erb 的相关 sn-p:

<%= form_for @vote do |f| %>
    <div class="right"> <%= image_submit_tag "plus32.png", :size => "16x16", :class => "squareicon" %>
        <span class="label success"><%= post.votes_count %></span>
    </div>

【问题讨论】:

  • 你能发布你的整个控制器吗?看起来 @posts 尚未设置 - 它为零。
  • 这就是问题所在 - 我分配了@posts = Post.popular 并且它有效。没有意识到我必须在 votes_controller 和 posts_controller 中分配它。有没有办法将@posts 保留在投票前使用的posts_controller 中(例如,Post.popular、Post.recent 等,具体取决于用户选择的内容)?

标签: ruby-on-rails validation


【解决方案1】:

在您的控制器中,在 else-branch 中,您有以下代码:

else
  flash[:failure] = "You did not vote"
  render 'posts/index'
end

您还需要在那里检索@posts 以缓解错误。或者改用redirect_to posts_path

希望这会有所帮助。

【讨论】:

  • 感谢redirect_to posts_path 工作以及分配@posts = Post.popularetc。让rails弹出警报然后返回上一个屏幕的最佳方法是什么(类似于在html erb中使用delete时:confirm =&gt; 'You sure?')?
  • 我不完全确定你的意思,但我建议使用 javascript。要么根本不去服务器,要么渲染javascript(在浏览器中执行)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-30
相关资源
最近更新 更多