ROR学习笔记(38)——继续查询&查询后的排序(ajax)

源文档在下面的URL:
https://github.com/kamionayuki/shop


用非AJAX的方式实现了查询和排序后,还是想用AJAX的方式实现。但在此之前,需要把cookies这个隐患排除掉。无意中有了一个惊人的发现,就是在views中xxx_path是可以随意加参数的。比如:
view中

<%= link_to "all products", products_path(para1: "txy", para2: " ai ", para3: "txl") %>

controller中

def index
    @para = params[:para1] +params[:para2] + params[:para2]
    @product = Product.all
end

用这个方法完全可以绕过cookies,以免把相关信息暴露出去。真的是太好了。
去掉了cookies后,就想用ajax来进行查询和排序,原理跟原来一样,只是用了ajax的方法了,具体操作如下:

  1. views中
    修改index.html.erb
<h1><%= link_to "Product", root_path %></h1>
  <%= will_paginate @products, renderer: BootstrapPagination::Rails %>  
  <%= form_tag search_products_path, method: "get", remote: true do %>
  <%= label_tag :s_price, "Price" %>
  <%= text_field_tag :s_price %>
  <%= submit_tag "Search" %>
  <% end %>
<table class="table table-striped">
  <%= render partial: 'thead', locals: {query: @query, order: @order} %>
  <%= render 'tbody' %>
</table>

新增加"views/products/_thead.html.erb",并且用params[:query]来传送当前页面的查询条件

<thead>
    <tr>
      <th><%= link_to "ID", sort_products_path(sort_by: order[:p_id], query: query), remote: true %></th>
      <th><%= link_to "Name", sort_products_path(sort_by: order[:p_name], query: query), remote: true %></th>
      <th><%= link_to "Price", sort_products_path(sort_by: order[:p_price], query: query), remote: true %></th>
      <th><%= link_to "Description", sort_products_path(sort_by: @order[:p_description], query: @query), remote: true  %></th>
      <th><%=t '.actions', :default => t("helpers.actions") %></th>
    </tr>
</thead>

新增加"views/products/_tbody.html.erb"

<tbody>
<% @products.each do |product| %>
  <tr>
    <td><%= link_to product.id, product_path(product) %></td>
    <td><%= product.name %></td>
    <td><%= product.price %></td>
    <td><%= product.description %></td>
    <td>
      <%= link_to t('.edit', :default => t("helpers.links.edit")),
                  edit_product_path(product), :class => 'btn btn-default btn-xs' %>
      <%= link_to t('.destroy', :default => t("helpers.links.destroy")),
                  product_path(product),
                  :method => :delete,
                  :data => { :confirm => t('.confirm', :default => t("helpers.links.confirm", :default => 'Are you sure?')) },
                  :class => 'btn btn-xs btn-danger' %>
    </td>
  </tr>
<% end %>
</tbody>

新增加"views/products/_products.js.erb"

$("thead").next().remove();
$("thead").after("<%= j render('tbody') %>");
$("tbody").prev().remove();
$("tbody").before("<%= j render(partial: 'thead', locals: {query: @query, order: @order}) %>");
  1. controller中没有多少变化,只是把cookies[:query]变成了params[:query],同时增加了@query用来把查询条件传给页面中的params[:query]。并且对@order进行了一下优化。
def index
    @products = Product.all.paginate(page: params[:page], per_page: 12)
    query = "1 = 1"
    @query = encode(query)
    respond_to do |format|
      format.html         
    end  
  end

  def sort
    @query = params[:query]
    query = decode(params[:query])
    order_query = params[:sort_by].join(" ")
    @products = Product.where(query).order(order_query).paginate(page: params[:page], per_page: 12)
    order_change(@order, params[:sort_by])
    render '_products'    
  end

  def search    
    if params[:s_price] == ""
      redirect_to :back
    else
      query = "price like \'%s\'" % params[:s_price]
      @products = Product.where(query).paginate(page: params[:page], per_page: 12)
      @query = encode(query)
      render '_products'      
    end   
  end
  
  private
    def order_init
      @order = {}
      @order[:p_price] = ["price", "desc"]
      @order[:p_id] = ["id", "desc"]
      @order[:p_name] = ["name", "desc"]
      @order[:p_description] = ["description", "desc"]
      return @order
    end

    def order_change(order, sort_by)      
      key = "p_" + sort_by.first
      value = sort_by.last
      value = value == "desc" ? "asc" : "desc"
      order[key.to_sym] = [sort_by.first, value]
    end
  1. routs中
resources :products do
    collection do
      get 'search'
      get 'sort'
    end
  end

大功告成!!!
wait~~~用ajax来实现查询和排序的好处是页面的url地址不会把相关信息显示出来。但上面的做法有两个问题

  1. 因为用的是“get”方法,所以当鼠标移动在表头的链接上时,仍然会显示相关信息(这个应该好处理,只要把sort改成post,views用button_to就可以了,具体如下)
    view中
  <thead>
    <tr>
      <th><%= button_to "ID", sort_products_path(sort_by: order[:p_id], query: query), remote: true, class: "btn btn_link" %></th>
      <th><%= button_to "Name", sort_products_path(sort_by: order[:p_name], query: query), remote: true, class: "btn btn_link" %></th>
      <th><%= button_to "Price", sort_products_path(sort_by: order[:p_price], query: query), remote: true, class: "btn btn_link" %></th>
      <th><%= button_to "Description", sort_products_path(sort_by: @order[:p_description], query: @query), 
                                                                    remote: true, class: "btn btn_link"  %></th>
      <th><%=t '.actions', :default => t("helpers.actions") %></th>
    </tr>
  </thead>

routes中

resources :products do
    collection do
      get 'search'
      post 'sort'
    end
  end
  1. 用了ajax进行排序和查询后。从此再也不能用will_paginate进行分页了。为这解决这个,花了两个多小时也没有搞定,也没有查到资料。不知道有没有好的方法来进行处理。参考了一下其它的网站,如果是ajax进行查询的排序的话,就没有分页功能。如果有分页功能的话,就没有用到ajax。因此以后如果有分页的需求,就不用ajax好了。吼吼~~~~

继续补充(重要)

可以对will_paginate进行ajax的分页了!!真的是无心插柳啊,哈哈哈哈。如下:

  1. index.html.erb修改一下:
<%- model_class = Product -%>
  <h1><%= link_to "Product", root_path %></h1>
  
  <%= render 'paginate' %>
  
  <%= form_tag search_products_path, method: "get", remote: true do %>
  <%= label_tag :s_price, "Price" %>
  <%= text_field_tag :s_price %>
  <%= submit_tag "Search" %>
  <% end %>
<table class="table table-striped">
  <%= render partial: 'thead', locals: {query: @query, order: @order} %>
  <%= render 'tbody' %>
</table>
  1. 增加一个_paginate.html.erb的文件
<%= will_paginate @products, renderer: BootstrapPagination::Rails %>
  1. _products.js.erb修改一下:
$("thead").next().remove();
$("thead").after("<%= j render('tbody') %>");
$("tbody").prev().remove();
$("tbody").before("<%= j render(partial: 'thead', locals: {query: @query, order: @order}) %>"); 
var flag = $(".pagination").prev();
$(".pagination").remove();
flag.after("<%= j render('paginate') %>");
$(".pagination a").attr('data-remote', 'true')
  1. 最要注意的是,排序的ajax不要用post方法,用get方法就OK了!!
    这真的是太意外了,哈哈哈
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,311评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,339评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,671评论 0 342
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,252评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,253评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,031评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,340评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,973评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,466评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,937评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,039评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,701评论 4 323
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,254评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,259评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,485评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,497评论 2 354
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,786评论 2 345

推荐阅读更多精彩内容