我有一个非常简单的rails应用程序,用户可以在其中投票。我实施的系统运作良好,但我想通过ajax方法在每次投票后更新投票数。
这是我的upvote系统,就像现在一样:
app / controllers / pins_controller.rb中的:
def upvote
@pin = Pin.friendly.find(params[:id])
@pin.votes.create(user_id: current_user.id)
respond_to do |format|
format.json { render json: { count: @pin.votes_count } }
end
end
在我的app / views / pins / index.html.erb中:
<%= link_to upvote_pin_path(pin), method: :post, remote: true do %>
<% if pin.votes.where(user_id: current_user.id).empty? %>
<span class="text-decoration: none;"><i class="fa fa-star"></i>
<% else %>
<span class="text-decoration: none;"><i class="fa fa-star" style="color:#c0392b"></i>
<% end %>
<% end %>
<span class="votes-count">
<%= pluralize(pin.votes.count, "") %>
</span>
因此,每当有人投票时,只有在刷新页面后才能看到投票。有什么想法吗?
我知道我应该在我的视图中调用upvote.js.erb文件中的ajax方法,但这就是我丢失的地方。
答案 0 :(得分:0)
我个人更喜欢避免那些凌乱的.js.erb文件,尽管你当然可以这样做。但是,一旦你进行了大量的Ajax调用,你就会得到大量的文件。 Ryan Bates对这种技术有一个非凡的截屏视频here。
没有这样做,这里是食谱。您需要在控制器操作中放置respond_to
块。现在,现在请求如何进入,你重定向到引脚路径,我假设是这种情况下的当前路径,它重新加载页面。那是你想要避免的。
默认情况下,Ajax请求以javascript或js请求类型的形式进入控制器。你可以根据需要切换那种类型(JSON是一种流行的选择),但是现在让它保持简单。因此,为js请求配置respond_to
块:
# app/controllers/pins_controller.rb
def upvote
@pin = Pin.friendly.find(params[:id])
if @pin.votes.create(user_id: current_user.id)
respond_to do |format|
format.html {
flash[:notice] = "Thanks for your recommendation."
redirect_to(pin_path)
}
format.js {
@count = @pin.votes.count.to_s
render nothing: true, count: @count # anything else you put in here will be available in the `success` callback on the JQuery ajax method.
}
end
else
format.html {
flash[:notice] = "Unable to process your request. Please try again."
redirect_to(pin_path)
}
format.js {
render nothing: true # anything else you put in here will be available in the `error` callback on the JQuery ajax method.
}
end
end
既然控制器已经传回了值,您需要在Ajax请求中检索它:
$.ajax({
.....
success:function(data){
$('span.votes-count').text(data.count)
}
当您使用此方法时,您将无法使用两件事(至少)。 flash消息和ruby复数方法。要绕过第二个,您需要在控制器中使用Ruby复数并返回所需的文本。要绕过第一个,你需要设置一些模仿Rails flash消息技术的javascript,并将flash消息传递回Ajax调用。
答案 1 :(得分:-1)
你应该把你的pinvotes放在一个带有类的范围内,以便在ajax完成后进行搜索
$(".fa.fa-star").click(function(){
var _this=$(this)
$.ajax({
.....
success:function(msg){
_this.parent().parent().find('.votes-count').html(msg); //Accesing the parent then you should acces a span to your votes
}
})
})