如何在页面刷新时更新Rails控制器变量?

时间:2016-12-21 23:11:13

标签: ruby-on-rails

我有一个管理Post列表的控制器,我在其中添加了过滤器。帖子有rating系统(0-5评级)。过滤器允许用户输入他们想要看到的评级,并且它将显示输入的评级和更高。

例如,我有10个帖子,其中7个评级为3.5或更高。如果用户在评分过滤器中输入3.5,则只会显示7个具有相应评级的帖子。

以下是代码:

index.html.erb

...
<%= form_tag posts_path, method: :get, class: "form-inline" do %> <!-- form_tag on posts path (index), use get method since we are displaying results and not altering/ submitting new data -->
  <div class="rating form-group">
    <%= label_tag :rating %>
    <%= number_field_tag :rating, params[:rating], step: 0.5, min: 0, max: 5, class: "form-control" %>
    <%= submit_tag "Search", name: nil, class: "btn btn-primary"%>
  </div>
<% end %>
...

这是我的索引:

def index
    @posts = Post.all
    @posts = Post.where("rating >= ?", params["rating"]) if params["rating"].present?
end

我的问题是,我想让用户在页面刷新时轻松删除过滤器。如何在每次用户刷新页面时删除过滤器,以便再次显示所有10个帖子?现在,如果我想在制作过滤器之后再次显示所有10个帖子,我要么必须转到字段框并删除我之前输入的号码3.5并重新提交表单,否则我必须更改网址手动从 http://localhost:3000/posts?utf8...&rating=3http://localhost:3000/posts;我认为用户只需刷新页面就会更方便。

我想我可以将其改写为,当用户刷新页面时,如何将控制器从@posts = Post.where...再次更改为@posts = Post.all

2 个答案:

答案 0 :(得分:1)

我不知道您的路线是什么,但我们假设您的posts_pathposts/index,并路由到index中的PostsController方法。

首先,我会更改您的路线配置,以便post/indexindex PostsController方法匹配,:get:post

# config/routes.rb
match 'posts/index' => 'posts#index', as: 'posts', via: [:get, :post]

接下来,我会更改您的表单以使用:post方法而不是:get

<%= form_tag posts_path, method: :post, class: "form-inline" do %> 
    <div class="rating form-group">
        <%= label_tag :rating %>
        <%= number_field_tag :rating, params[:rating], 
                             step: 0.5, min: 0, max: 5, class: "form-control" %>
        <%= submit_tag "Search", name: nil, class: "btn btn-primary"%>
    </div>
<% end %>

最后,我会将控制器的where子句更改为接受params[:rating](如果提供),但如果params[:rating]nil,则默认为0:

def index
    @posts = Post.where("rating >= ?", params[:rating]||=0) 
end

这当然假设您没有负面评价的帖子......如果您这样做,您可以默认为足够负数(所有帖子的评级都高于)。

现在,当用户提交表单时,该查询字符串中的网址将不再包含params[:rating]

希望这有帮助!

答案 1 :(得分:0)

此处的问题是刷新页面时您的查询字符串会停留。

所以一种方法是替换url并删除查询字符串。使用现代浏览器中的history APi,您可以执行此操作。

history.replaceState({}, 'some title', '/');

您只需将其插入文档/ head ready回调即可。因此,在您的用户获得带有评级的响应后,您将网址更改回没有查询字符串的网址。因此,当它刷新时,它会向您的服务器发出没有评级查询字符串的请求。

但请注意,您的用户将无法根据评分为您的网页添加书签。如果您想这样做,您需要将获取请求切换为发布请求。查看此维基页面了解更多信息。

https://en.wikipedia.org/wiki/Post/Redirect/Get