【问题标题】:Why is Rails not setting a cookie variable correctly when using AJAX?为什么在使用 AJAX 时 Rails 没有正确设置 cookie 变量?
【发布时间】:2014-02-25 16:08:38
【问题描述】:

当我尝试在远程操作中设置 cookie 时,它​​的设置不正确。

阿贾克斯:

控制器/故事:

def vote
    unless cookies[params[:story_id]]
        @story = Story.find(params[:story_id])
        @story.rating += 1
        @story.save
        cookies[params[:story_id]] = true
    end
end

观点/故事:

<% unless cookies[story.id] %>
    <%= link_to "▲", story_vote_path(story), :remote => true, :method => "put", class: :vote %>
<% end %>

非 ajax:

控制器/故事:

def vote
    unless cookies[params[:story_id]]
        @story = Story.find(params[:story_id])
        @story.rating += 1
        @story.save
        cookies[params[:story_id]] = true
    end
    redirect_to root_url
end

观点/故事:

<% unless cookies[story.id] %>
    <%= link_to "▲", story_vote_path(story), :method => "put", class: :vote %>
<% end %>

在之前的代码中,无论链接是否被点击,它仍然会出现并且可以用来再次投票。但是在后者中,链接不再出现,您不能再次投票。 我看了看,发现set_cookie头可以从ajax调用中发回,我哪里出错了?

【问题讨论】:

  • ajax 请求中的投票操作后呈现的视图是什么?你需要一个js来隐藏链接
  • 我明白这一点。然而,在重新加载后,链接仍然出现,除非 cookies[story.id] 应该阻止。
  • 仅供参考 Ruby 不支持这一行:@story.rating += 1 - 你必须使用 @story.rating = @story.rating + 1
  • 我不确定它是否有效,所以我尝试了,它确实增加了计数器。

标签: ruby-on-rails ajax cookies


【解决方案1】:

我不确定这是否是问题所在,但如果您尝试通过 Ajax 创建 cookie,这是否意味着您必须刷新 HTTP 请求才能使该 cookie 与 Rails 一起使用?

你可以做几件事来测试这个:

  1. 刷新您的页面(并在您的视图中包含cookie(查看是否已设置))
  2. 设置Rails.logger.info()命令查看是否设置了cookie
  3. 尝试其他方法

刷新

#app/views/stories/show.html.erb
<%= cookies[story.id] %>

在您的视图中包含此代码将输出该 cookie 的任何内容。这意味着如果您执行 ajax 请求,您可以刷新页面以查看它是否已被实际设置(并且没有被您的 ajax 绑定代码捕获)


记录器

unless cookies[params[:story_id]]
    @story = Story.find(params[:story_id])
    @story.increment!(:rating)

    cookies[params[:story_id]] = true
    Rails.logger.info(cookies[story.id])
end

这将在 Rails 日志中输出 cookie,让您查看它是否真的被设置


Ajax

您对 cookie 的使用似乎有些低效。我更喜欢像这样使用简单的respond_to 系统:

#app/controllers/stories_controller.rb
def vote
    unless cookies[params[:story_id]]
        @story = Story.find(params[:story_id])
        @story.increment!(:rating)
    end
    respond_to do |format| 
        format.html { redirect_to root_url }
        format.js
    end
end

#app/views/stories/vote.js.erb
<% if @story %>
    $("a.vote").fadeOut(150, function() {
        $(this).hide();
    });
<% end %>

每次您使用 Ajax 执行 vote 操作时,都会调用此 .js.erb。它将执行将直接影响您的预加载页面的功能


.increment!

让你的代码更干燥的东西:

unless cookies[params[:story_id]]
    @story = Story.find(params[:story_id])
    @story.increment!(:rating)

    cookies[params[:story_id]] = true
end

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-04-06
    • 2020-12-05
    • 1970-01-01
    • 2019-08-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多