【问题标题】:Rails 6 - Values from view not reaching the controllerRails 6 - 视图中的值未到达控制器
【发布时间】:2020-05-25 17:46:44
【问题描述】:

=> Rails 6.0.3

日期未从视图/表单传递到控制器。

什么有效

  1. 在视图中,日期字段预填充了来自 /models/case_search.rb - def initialize(params) 的默认值p>

  2. 从数据库中提取案例列表

    SELECT "cases".*
    FROM "cases"
    WHERE (closed_date BETWEEN '2020-05-23' AND '2020-05-25')
    

什么失败了

  1. 当我更改表单字段中的日期时,URL 更改为:

    http://localhost:3000/teams/5?Date+from=2020-05-10&Date+to=2020-05-15&commit=List

    但病例列表保持不变:

    SELECT "cases".*
    FROM "cases"
    WHERE (closed_date BETWEEN '2020-05-23' AND '2020-05-25')
    

不知何故,@search 变量到达控制器是空的,它总是默认为 /models/case_search.rb 中设置的值 - def initialize(params) - def parsed_date(date_string, default).

有人能找出问题所在吗?

我在/teams/show.html.erb有以下表格:

<%= form_tag team_path, method: "get" do %>
    <%= text_field_tag 'Date from', @search.date_from %>
    <%= text_field_tag 'Date to', @search.date_to %>
    <%= submit_tag 'List', class: 'btn btn-dark' %>
<% end %>

控制器teams_controller.rb文件有:

def show
    @team = Team.find(params[:id])
    @team_owner = User.find(@team.owner)
    @search = CaseSearch.new(params[:search])
    @cases = @search.scope
end

我创建了一个新的模型文件/models/case_search.rb 来处理搜索:

class CaseSearch
attr_reader :date_from, :date_to

def initialize(params)
    params ||= {}
    @date_from = parsed_date(params[:date_from], 2.days.ago.to_date.to_s)
    @date_to = parsed_date(params[:date_to], Date.today.to_s)
end

def scope
    Case.where('closed_date BETWEEN ? AND ?', @date_from, @date_to)
end

private
    def parsed_date(date_string, default)
        Date.parse(date_string)
     rescue ArgumentError, TypeError
        default
    end
end

【问题讨论】:

  • 如果我将文件 /models/case_search.rb 更改为:def initialize(params) params ||= {} @date_from = Date.parse(params[:date_from]) @date_to = Date.parse(params[:date_to]) end 我收到以下错误:TeamsController 中的 TypeError#show no implicit conversion of nil into String @date_from = Date.parse(参数[:date_from])

标签: ruby-on-rails ruby


【解决方案1】:

问题出在以下几行:

在控制器中:

@search = CaseSearch.new(params[:search])

在 case_search 中,您访问 params[:date_from]params[:date_to]

在视图中:

<%= text_field_tag 'Date from', @search.date_from %>
<%= text_field_tag 'Date to', @search.date_to %>

从上面我假设您期望params 具有以下结构:

{search: {date_from: 'value', date_to: 'value'}}

这不会反映在表单中。

text_field_tag 'Date from' 行将使控制器中params['Date from'] 下的值可用,这不是您想要的。而是将视图更改为:

<%= text_field_tag 'search[date_from]', @search.date_from %>
<%= text_field_tag 'search[date_to]', @search.date_to %>

所以它符合您期望的结构。

指南Action Controller Overview 有一个专门讨论这个的部分:

4.1 Hash and Array Parameters

params 哈希不限于一维键和值。 它可以包含嵌套数组和散列。要发送一组值, 将一对空方括号“[]”附加到键名:

GET /clients?ids[]=1&ids[]=2&ids[]=3

本示例中的实际 URL 将被编码为“/clients?ids%5b%5d=1&ids%5b%5d=2&ids%5b%5d=3”作为“[”和“]” URL 中不允许使用字符。大多数时候你不必 担心这个,因为浏览器会为你编码,Rails 会自动解码,但如果你发现自己不得不 手动将这些请求发送到服务器,您应该保留它 介意。

params[:ids] 的值现在将是 ["1", "2", "3"]。注意 参数值始终是字符串; Rails 不会尝试猜测 或强制转换类型。

params 中的 [nil][nil, nil, ...] 等值是 出于安全原因,默认替换为[]。看 Security Guide 了解更多信息。

要发送散列,请将密钥名称包含在括号内:

<form accept-charset="UTF-8" action="/clients" method="post">
  <input type="text" name="client[name]" value="Acme" />
  <input type="text" name="client[phone]" value="12345" />
  <input type="text" name="client[address][postcode]" value="12345" />
  <input type="text" name="client[address][city]" value="Carrot City" />
</form>

提交此表单时,params[:client] 的值将是{ "name" =&gt; "Acme", "phone" =&gt; "12345", "address" =&gt; { "postcode" =&gt; "12345", "city" =&gt; "Carrot City" } }。注意嵌套哈希 params[:client][:address].

params 对象的作用类似于哈希,但允许您使用符号和 字符串可以作为键互换。

【讨论】:

    【解决方案2】:

    您的text_field_tag 似乎与您要检索的内容不同。尝试更改为:

    <%= text_field_tag :date_from, @search.date_from %>
    <%= text_field_tag :date_to, @search.date_to %>
    

    【讨论】:

    • 没有改变行为,变量@search保持不变:localhost:3000/teams/…&lt;%= debug @search %&gt; --- !ruby/object:CaseSearch date_from: '2020-05-23' date_to: '2020-05-25'
    • params[:search] 的输出是什么?
    猜你喜欢
    • 2021-07-13
    • 1970-01-01
    • 2020-06-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-13
    相关资源
    最近更新 更多