Tal*_*boy 1 ruby ruby-on-rails ruby-on-rails-3 ruby-on-rails-3.1
我正在尝试使用此声明:
@vote = Vote.where(:resource_id => params[:id], :user_id => current_user.id).first_or_create(:value => 1)
Run Code Online (Sandbox Code Playgroud)
这是一个upvote或downvote.如果该行不存在于DB中,则应该创建它(如果它们从未在该帖子上投票),则应该使用-1,0,1来修改该值.
如果他们第二次点击upvote,它需要"撤销"投票并将行"值"设置为0而不是1.同样的事情发生在downvote但是现在只是upvote函数.
我在调试这个语句时遇到了麻烦.我需要基本上区分它是保存的记录还是创建的记录.如果我把:
@vote = Vote.where(:resource_id => 25, :user_id => 1)
@vote.exists?
Run Code Online (Sandbox Code Playgroud)
我明白了 true
但如果我把它...(和记录存在,它只是在上面工作)..
@vote = Vote.where(:resource_id => 25, :user_id => 1).first_or_create(:value => 1)
@vote.exists?
Run Code Online (Sandbox Code Playgroud)
我得到... NoMethodError:未定义的方法`存在?' 为#
在查看两个对象的类之后,我看到一个是"投票",一个是"ActiveRecord :: Relation".
我的最终目标是以某种方式重构这个(主要是它检查投票值是否已经为1的部分,如果这样设置为零(撤消投票),否则将其置于1
这是我开始尝试使用first_or_create重构之前的代码.它漫长而丑陋.
if @vote.exists?
# Check if they have already voted
if @vote.first.value == 1
@vote.first.value = 0
else
@vote.first.value = 1
end
flash[:notice] = "previous vote modified"
@vote.first.save
else
# Create a new Vote instance, save it
@vote = Vote.new(:resource_id => params[:id], :user_id => current_user.id, :value => 1)
if @vote.valid?
@vote.save
flash[:notice] = "New vote added"
else
@vote.save
flash[:notice] = (@vote.errors.full_messages).to_s
end
end
Run Code Online (Sandbox Code Playgroud)
我宁愿使用Rails魔术find_or_create_by方法.
在这里查看"基于动态属性的查找器":
http://api.rubyonrails.org/classes/ActiveRecord/Base.html
您可以像使用动态查找方法一样使用它,但是如果它不存在,则传入要添加的额外变量以创建投票.
在你的情况下,它是这样的:
@vote = Vote.find_or_create_by_resource_id_and_user_id(25, 1, :value => 1)
Run Code Online (Sandbox Code Playgroud)
如果您不希望它立即创建,您可以使用find_or_initialize_by哪个基本上创建一个Vote.new不保存.
| 归档时间: |
|
| 查看次数: |
1035 次 |
| 最近记录: |