从View文件中我传递了url中的属性:
%= link_to piece_path(@current_piece, file: file, rank: rank), method: :patch do %>
这会提供http://localhost:3030/pieces/%23?file=8&rank=8
我需要从这个url中提取文件和排名的值,以更新数据库字段(移动后棋子的坐标)。
在Controller I中尝试使用Addressable gem:
def update
(some code)
current_piece.update_attributes(piece_params)
(more code)
end
private
def piece_params
uri = Addressable::URI.parse(request.original_url)
file = uri.query_values.first ## I don't know if "first"
rank = uri.query_values.last ## and "last" methods will work
params.require(:piece).permit({:file => file, :rank => rank})
end
当我检查uri
时,我得到:#<Addressable::URI:0x3fa7f21cc01c URI:http://test.host/pieces/2>
没有跟踪网址的属性哈希。因此uri.query_values
会返回nil
。我不知道如何在测试中反映这样的事情。
错误消息:
1) PiecesController pieces#update should update the file and rank of the chess piece when moved
Failure/Error: file = uri.query_values.first
NoMethodError:
undefined method `first' for nil:NilClass
在Controller_spec中:
describe "pieces#update" do
it "should update the file and rank of the chess piece when moved" do
piece = FactoryGirl.create(:piece)
sign_in piece.user
patch :update, params: { id: piece.id, piece: { file: 3, rank: 3}}
piece.reload
expect(piece.file).to eq 3
expect(piece.rank).to eq 3
end
我无法检查逻辑是否可以从localhost浏览器中运行(我此刻没有碎片对象,所以我遇到了错误)。还在努力。
我的问题是考试;但是,如果有建议以不同的方式从网址中提取属性我全都耳朵!
答案 0 :(得分:1)
您不需要手动解析请求URI以在Rails中获取查询参数。
Rails构建在Rack CGI接口之上,它解析请求URI和请求体,并提供参数作为params散列。
例如,如果你有:
resources :things
class ThingsController < ApplicationController
def index
puts params.inspect
end
end
请求/things?foo=1&bar=2
会输出如下内容:
{
foo: 1,
bar: 2,
action: "index",
controller: "things"
}
link_to method: :patch
使用JQuery UJS允许您使用<a>
元素通过除GET之外的其他方法发送请求。它通过附加一个创建表单的javascript处理程序并将其发送到HREF属性中的URI来实现。
然而,不像&#34;正常形式&#34;在rails中,params不是嵌套的:
<%= link_to piece_path(@current_piece, file: file, rank: rank), method: :patch do %>
将给出以下参数哈希:
{
file: 1,
rank: 2
}
不
{
piece: {
file: 1,
rank: 2
}
}
如果你想要嵌套键,你必须提供params:
<%= link_to piece_path(@current_piece, "piece[file]" => file, "piece[rank]" => rank), method: :patch do %>
答案 1 :(得分:0)
如果您的网址为export function catcher<S, P, T extends new (... args:any[]) => React.Component<S, P>>(constructor:T) {
class HOC extends constructor {
}
return HOC;
}
,您应该可以:
http://localhost:3030/pieces/%23?file=8&rank=8
然后通过def piece_params
params.require(:piece).permit(:rank, :file)
end
和params[:rank]
在您的操作中访问它们
在尝试分配值之前,我通常使用params[:file]
来确保params在那里。这样的事情应该有效:
params[:file].present?
FWIW,您可能不应该使用URL字符串将params传递给p = {}
if params[:rank].present?
p[:rank] = params[:rank]
end
if params[:file].present?
p[:file] = params[:file]
end
current_piece.update_attributes(p)
请求。您可以考虑通过表单或其他方式传递它们。
答案 2 :(得分:0)
button_to
有效;在视图文件中:
<%= button_to piece_path(@current_piece), method: :patch, params: {piece: {file: file, rank: rank}} do %>
在控制器中保持简单:
def piece_params
params.require(:piece).permit(:rank, :file)
end