【发布时间】: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 等,具体取决于用户选择的内容)?