我正在使用Rails v4,我有一个通过脚手架生成的控制器。我希望更新操作的路由基于我定义的模型的machine_name
属性,而不是ID。但是,在routes.rb中,正在为模式资源生成路由。
以下是资源的默认路由:
rooms GET /rooms(.:format) rooms#index
POST /rooms(.:format) rooms#create
new_room GET /rooms/new(.:format) rooms#new
edit_room GET /rooms/:id/edit(.:format) rooms#edit
room GET /rooms/:id(.:format) rooms#show
PATCH /rooms/:id(.:format) rooms#update
PUT /rooms/:id(.:format) rooms#update
DELETE /rooms/:id(.:format) rooms#destroy
因此,对于PATCH / PUT请求,更新方法将在我提交时触发,例如/ rooms / folsom_prison。然后Rails会将folsom_prison视为ID,并尝试将参数与id
列中的值匹配,而不是machine_name
列。如何让Rails更改正在查看记录的列?
我正在使用的当前代码:
# PATCH/PUT /rooms/1
# PATCH/PUT /rooms/1.json
def update
@room = Room.find_by_machine_name(params[:id])
room_params.delete(:id)
respond_to do |format|
if Room.update(@room.id,room_params)
format.html { redirect_to @room, notice: 'Room was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: 'edit' }
format.json { render json: @room.errors, status: :unprocessable_entity }
end
end
end
来自日志的结果错误消息:
Started PATCH "/rooms/folsom_prison" for 127.0.0.1 at 2013-09-13 16:28:53 -0400
Room Load (0.1ms) SELECT "rooms".* FROM "rooms" WHERE "rooms"."id" = ? LIMIT 1 [["id", "folsom_prison"]]
ActiveRecord::RecordNotFound (Couldn't find Room with id=folsom_prison):
app/controllers/rooms_controller.rb:69:in `set_room'
...以及我正在测试的cURL请求:
curl -i -H "Accept: application/json" -X PATCH -d "room[booked]=1" localhost:3000/rooms/folsom_prison
答案 0 :(得分:1)
您正在寻找friendly_id gem:https://github.com/norman/friendly_id
答案 1 :(得分:1)
你不想在Rails 4中使用find_by_*
助手。这就是你想要做的事情
Room.where(machine_name: params[:id])
要让您的路线正常运作,您需要覆盖to_param
型号中的Room
require "uri"
class Room < ActiveRecord::Base
# ...
def to_param
URI.escape(machine_name)
end
end
假设你有一个房间实例
@room = Room.new machine_name: "foo"
当你创建链接时,一切都会很精彩!
<%= link_to @room.machine_name, @room %>
#=> <a href="/rooms/foo">foo</a>
答案 2 :(得分:0)
@naomik对于已删除的find_by_*
方法是正确的,但是,find_by
方法取代了where
方法,而不是Room.find_by(machine_name: params[:id])
。
where
这将找到1条记录并将其返回,但{{1}}将找到与此匹配的所有记录,并始终以数组形式返回它们,即使只有一条记录。