新手问题 Rails 5 ActionController::Parameters 问题

lzding · September 14, 2016 · Last by lzding replied at September 18, 2016 · 3366 hits

大家好,我在开发中遇到一个问题,希望高手指导一下。问题是这样的: 我用的 gem 'will_paginate', '~> 3.1.0'做的分页功能,又加了一个 search 方法做搜索功能,前面都是 OK 的,在使用搜索功能之后,页面也是正常的,但是我审查页面元素时发现了问题,如下图: 图中所看到的下一页的链接(/downtime_records/search?downtime_record=%23%3CActionController%3A%3AParameters%3A0x007fab4043d300%3E&page=2)有问题,但是我不知道是怎么生成的,当我点击下一页的时候,后台无法解析这个参数就报错了,报错如图:

贴上相关代码

Controller 代码剪切:

def search
  @condition=params[@model].to_unsafe_h

  query=model.all #.unscoped
  @condition.each do |k, v|
    if (v.is_a?(Fixnum) || v.is_a?(String)) && !v.blank?
      puts @condition.has_key?(k+'_fuzzy')
      if @condition.has_key?(k+'_fuzzy')
        query=query.where("#{k} like ?", "%#{v}%")
      else
        query=query.where(Hash[k, v])
      end
      instance_variable_set("@#{k}", v)
    end

    if v.is_a?(Hash) && v.values.count==2 && v.values.uniq!=['']
      values=v.values.sort
      values[0]=Time.parse(values[0]).utc.to_s if values[0].is_date? & values[0].include?('-')
      values[1]=Time.parse(values[1]).utc.to_s if values[1].is_date? & values[1].include?('-')

      query=query.where(Hash[k, (values[0]..values[1])])
      v.each do |kk, vv|
        instance_variable_set("@#{k}_#{kk}", vv)
      end
    end
  end

  if block_given?
    query=(yield query)
  end

  if params.has_key? "download"
    send_data(query.to_xlsx(query),
              :type => "application/vnd.openxmlformates-officedocument.spreadsheetml.sheet",
              :filename => @model.pluralize+".xlsx")
    #render :json => query.to_xlsx(query)
  else
    instance_variable_set("@#{@model.pluralize}", query.paginate(:page => params[:page]))
    render :index
  end
end

private
# Use callbacks to share common setup or constraints between actions.
def set_downtime_record
  @downtime_record = DowntimeRecord.find(params[:id])
end

# Never trust parameters from the scary internet, only allow the white list through.
def downtime_record_params
  params.require(:downtime_record).permit(:fors_werk, :fors_faufnr, :fors_faufpo, :fors_lnr, :machine_id, :pk_sch, :pk_datum, :pk_sch_std,
                                          :pk_sch_t, :craft_id, :pd_teb, :pd_stueck, :pd_auss_ruest, :pd_auss_prod, :pd_bemerk, :pd_user,
                                          :pd_erf_dat, :pd_von, :pd_bis, :downtime_code_id, :pd_std, :pd_laenge, :pd_rf, :is_naturl,
                                          :pd_bemerk_fuzzy, :pk_datum_start, :pk_datum_end,:page)
end

View 代码剪切:

<div class="col-sm-12">
  <div class="digg_pagination">
    <div class="page_info">
      <%= page_entries_info @downtime_records %>
    </div>
    <%= will_paginate @downtime_records, :container => true %>
  </div>
</div>

<table>
  <thead>
  <tr>
    <th>NO.</th>
    <th>工厂代码</th>
    <th>订单号</th>
    <th>订单序号</th>
    <th>Fors lnr</th>
    <th>机台号</th>
    <th>班次</th>
    <th>入账日期</th>
    <th>Pk sch std</th>
    <th>班组</th>
    <th>工艺</th>
    <th>标准操作工时(m)</th>
    <th>产量</th>
    <th>生产前报废</th>
    <th>生产过程中报废</th>
    <th>订单+序号</th>
    <th>账号</th>
    <th>实际生产日期</th>
    <th>停机开始</th>
    <th>停机结束</th>
    <th>停机代码</th>
    <th>停机时间(h)</th>
    <th>线长(mm)</th>
    <th>Pd rf</th>
    <th>是否系统添加</th>
    <th colspan="3"></th>
  </tr>
  </thead>

  <tbody>
  <% @downtime_records.each_with_index do |downtime_record, index| %>
      <tr>
        <td><%= index+@downtime_records.offset+1 %></td>
        <td><%= downtime_record.fors_werk %></td>
        <td><%= downtime_record.fors_faufnr %></td>
        <td><%= downtime_record.fors_faufpo %></td>
        <td><%= downtime_record.fors_lnr %></td>
        <td><%= downtime_record.machine.nr %></td>
        <td><%= downtime_record.pk_sch %></td>
        <td><%= downtime_record.pk_datum.localtime.strftime('%Y%m%d') %></td>
        <td><%= downtime_record.pk_sch_std %></td>
        <td><%= downtime_record.pk_sch_t %></td>
        <td><%= downtime_record.craft.nr %></td>
        <td><%= downtime_record.pd_teb %></td>
        <td><%= downtime_record.pd_stueck %></td>
        <td><%= downtime_record.pd_auss_ruest %></td>
        <td><%= downtime_record.pd_auss_prod %></td>
        <td><%= downtime_record.pd_bemerk %></td>
        <td><%= downtime_record.pd_user %></td>
        <td><%= downtime_record.pd_erf_dat.localtime.strftime('%Y%m%d') %></td>
        <td><%= downtime_record.pd_von.localtime.strftime('%Y%m%d  %H:%M:%S') %></td>
        <td><%= downtime_record.pd_bis.localtime.strftime('%H:%M:%S') %></td>
        <td><%= downtime_record.downtime_code.nr %></td>
        <td><%= downtime_record.pd_std %></td>
        <td><%= downtime_record.pd_laenge %></td>
        <td><%= downtime_record.pd_rf %></td>
        <td><%= downtime_record.is_naturl %></td>
        <td><%= link_to 'Show', downtime_record %></td>
        <td><%= link_to 'Edit', edit_downtime_record_path(downtime_record) %></td>
        <td><%= link_to 'Destroy', downtime_record, method: :delete, data: {confirm: 'Are you sure?'} %></td>
      </tr>
  <% end %>
  </tbody>
</table>

<div class="digg_pagination">
  <%= will_paginate @downtime_records, :container => false %>
</div>

View 代码剪切:

<div class="all-search">
  <form method="get" action="<%= send("search_#{@model.pluralize}_path") %>">
    <div class="col-sm-12">
      <div class="col-sm-4">
        机器号:
        <%= select_tag('downtime_record[machine_id]', options_from_collection_for_select(Machine.all, :id, :nr, @machine_id), include_blank: true) %>
      </div>
      <div class="col-sm-3">
        订单号:
        <input type="text" name="downtime_record[pd_bemerk]" value="<%= @pd_bemerk %>"/>
      </div>
      <div class="col-sm-4">
        停机代码:
        <%= select_tag('downtime_record[downtime_code_id]', options_from_collection_for_select(DowntimeCode.all, :id, :nr, @downtime_code_id), include_blank: true) %>
      </div>
    </div>


    <div class="col-sm-12">
      <div class="col-sm-4">
        <input type="submit" value="查 找" class="btn btn-primary" style="width: 150px;"/>
      </div>
    </div>
  </form>
</div>

在 will paginate gem 中找到了原因,我修改了 action_view.rb 文件中的一个函数:

def merge_get_params(url_params)
   if @template.respond_to? :request and @template.request and @template.request.get?
     symbolized_update(url_params, @template.params.is_a?(ActionController::Parameters)==true ? @template.params.to_unsafe_h : @template.params)
   end
   url_params
 end

但是觉得这个方法并不好,希望大家能给出更好的解决办法

根据这个issue的解决方法和你的差不多

<%= will_paginate @downtime_records, params: params.to_unsafe_h %>

@w7938940 nice, 我之前没有想到,谢谢

lzding closed this topic. 20 Sep 13:51
You need to Sign in before reply, if you don't have an account, please Sign up first.