设置to_param方法后,无法创建嵌套资源
After setting to_param method, nested resource cannot be created
我有 2 个模型,Room 和 Message,Room has_many :messages
。
rooms#show 的 url 是 rooms/:room_id
,我使用 to_param
方法将 url 显示为 rooms/:url_token
。之后,由于错误,我无法创建消息:
ActionController::UrlGenerationError in MessagesController#create
No route matches {:action=>"show", :controller=>"rooms", :room_url_token=>"ieghuEJA3WfgXuXqdR8XEGMZrYJF2nwnnoOGGwt5OApDGXGpPZL6Y368AqonrcbtLxeWgXkH/D5eRam+cvgSTDh7wM2hFW4jqpnHoOw/RbDgnQNxn14y6h8GouQRDR4Kj+IMmA=="}, missing required keys: [:url_token]
我该如何解决?或者如何用消息改变room_url?请帮忙。
rake routes
结果
signup GET /signup(.:format) rooms#new
POST /signup(.:format) rooms#create
room_messages POST /rooms/:room_url_token/messages(.:format) messages#create
rooms POST /rooms(.:format) rooms#create
new_room GET /rooms/new(.:format) rooms#new
room GET /rooms/:url_token(.:format) rooms#show
messages_controller.rb
class MessagesController < ApplicationController
before_action :set_room
def create
@message = @room.messages.new(message_params)
if @message.save
flash[:success] = "posted"
redirect_to @room
else
render 'new'
end
end
private
def message_params
params.require(:message).permit(:name, :content)
end
def set_room
@room = Room.find_by(url_token: params[:url_token])
end
end
rooms_controller.rb
class RoomsController < ApplicationController
before_action :set_room, only: :show
def show
@room = Room.find_by(url_token: params[:url_token])
@messages = @room.messages.paginate(page: params[:page])
@message = @room.messages.new
end
private
def set_room
@room = Room.find_by(url_token: params[:url_token])
end
end
url_token在房间模型中创建:
class Room < ApplicationRecord
has_many :messages, dependent: :destroy
validates :title, presence: true, length: { maximum: 100 }
validates :url_token, presence: true, uniqueness: true
before_validation :generate_url_token
def to_param
url_token
end
private
def generate_url_token
self.url_token = SecureRandom.base64(100)
end
end
消息模型是
class Message < ApplicationRecord
belongs_to :room
default_scope -> { order(created_at: :asc) }
validates :room_id, presence: true
validates :name, presence: true, length: { maximum: 100 }
validates :content, presence: true, length: { maximum: 1000 }
end
完整的错误日志是
Started POST "/rooms/ieghuEJA3WfgXuXqdR8XEGMZrYJF2nwnnoOGGwt5OApDGXGpPZL6Y368AqonrcbtLxeWgXkH%2FD5eRam+cvgSTDh7wM2hFW4jqpnHoOw%2FRbDgnQNxn14y6h8GouQRDR4Kj+IMmA==/messages" for 153.203.168.240 at 2019-03-17 01:32:34 +0900
Cannot render console from 153.203.168.240! Allowed networks: 127.0.0.1, ::1, 127.0.0.0/127.255.255.255
(0.5ms) SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
? /root/.rbenv/versions/2.5.3/lib/ruby/gems/2.5.0/gems/activerecord-5.2.2.1/lib/active_record/log_subscriber.rb:98
Processing by MessagesController#create as HTML
Parameters: {"utf8"=>"?", "authenticity_token"=>"Rt2ek/0VX3TLN925qJkg7zYYlL3e7VUf6BF/mRsze5sVigmTjVzm6HcKz66RYuJCtjWl3T0Iv9qlQB47zf/f1w==", "message"=>{"name"=>"pryn", "content"=>"kokok"}, "commit"=>"Post", "room_url_token"=>"ieghuEJA3WfgXuXqdR8XEGMZrYJF2nwnnoOGGwt5OApDGXGpPZL6Y368AqonrcbtLxeWgXkH/D5eRam+cvgSTDh7wM2hFW4jqpnHoOw/RbDgnQNxn14y6h8GouQRDR4Kj+IMmA=="}
Room Load (0.4ms) SELECT "rooms".* FROM "rooms" WHERE "rooms"."url_token" IS NULL LIMIT [["LIMIT", 1]]
? app/controllers/messages_controller.rb:22
(0.2ms) BEGIN
? app/controllers/messages_controller.rb:7
Message Create (1.0ms) INSERT INTO "messages" ("name", "content", "room_id", "created_at", "updated_at") VALUES (, , , , ) RETURNING "id" [["name", "pryn"], ["content", "kokok"], ["room_id", 1], ["created_at", "2019-03-16 16:32:34.837275"], ["updated_at", "2019-03-16 16:32:34.837275"]]
? app/controllers/messages_controller.rb:7
(0.5ms) COMMIT
? app/controllers/messages_controller.rb:7
Redirected to
Completed 500 Internal Server Error in 40ms (ActiveRecord: 7.9ms)
ActionController::UrlGenerationError (No route matches {:action=>"show",
:controller=>"rooms", :url_token=>nil}, missing required keys:
[:url_token]):
在routes.rb
Rails.application.routes.draw do
resources :rooms, only: [:create, :new, :show], param: :url_token do
resources :messages, only: [:create]
end
end
根据你的路线:
room_messages POST /rooms/:room_url_token/messages(.:format)
这是发送给请求的 :room_url_token
参数,而不是 :url_token
。
您可以在此处查看日志:
Processing by MessagesController#create as HTML
Parameters: {"utf8"=> ... "room_url_token"=>"ieghuEJA3WfgXuXqdR8XEGMZrYJF2nwnnoOGGwt5OApDGXGpPZL6Y368AqonrcbtLxeWgXkH/D5eRam+cvgSTDh7wM2hFW4jqpnHoOw/RbDgnQNxn14y6h8GouQRDR4Kj+IMmA=="}
在您的 MessagesController
中,像这样修复 set_room
方法:
def set_room
@room = Room.find_by(url_token: params[:room_url_token])
end
我有 2 个模型,Room 和 Message,Room has_many :messages
。
rooms#show 的 url 是 rooms/:room_id
,我使用 to_param
方法将 url 显示为 rooms/:url_token
。之后,由于错误,我无法创建消息:
ActionController::UrlGenerationError in MessagesController#create
No route matches {:action=>"show", :controller=>"rooms", :room_url_token=>"ieghuEJA3WfgXuXqdR8XEGMZrYJF2nwnnoOGGwt5OApDGXGpPZL6Y368AqonrcbtLxeWgXkH/D5eRam+cvgSTDh7wM2hFW4jqpnHoOw/RbDgnQNxn14y6h8GouQRDR4Kj+IMmA=="}, missing required keys: [:url_token]
我该如何解决?或者如何用消息改变room_url?请帮忙。
rake routes
结果
signup GET /signup(.:format) rooms#new
POST /signup(.:format) rooms#create
room_messages POST /rooms/:room_url_token/messages(.:format) messages#create
rooms POST /rooms(.:format) rooms#create
new_room GET /rooms/new(.:format) rooms#new
room GET /rooms/:url_token(.:format) rooms#show
messages_controller.rb
class MessagesController < ApplicationController
before_action :set_room
def create
@message = @room.messages.new(message_params)
if @message.save
flash[:success] = "posted"
redirect_to @room
else
render 'new'
end
end
private
def message_params
params.require(:message).permit(:name, :content)
end
def set_room
@room = Room.find_by(url_token: params[:url_token])
end
end
rooms_controller.rb
class RoomsController < ApplicationController
before_action :set_room, only: :show
def show
@room = Room.find_by(url_token: params[:url_token])
@messages = @room.messages.paginate(page: params[:page])
@message = @room.messages.new
end
private
def set_room
@room = Room.find_by(url_token: params[:url_token])
end
end
url_token在房间模型中创建:
class Room < ApplicationRecord
has_many :messages, dependent: :destroy
validates :title, presence: true, length: { maximum: 100 }
validates :url_token, presence: true, uniqueness: true
before_validation :generate_url_token
def to_param
url_token
end
private
def generate_url_token
self.url_token = SecureRandom.base64(100)
end
end
消息模型是
class Message < ApplicationRecord
belongs_to :room
default_scope -> { order(created_at: :asc) }
validates :room_id, presence: true
validates :name, presence: true, length: { maximum: 100 }
validates :content, presence: true, length: { maximum: 1000 }
end
完整的错误日志是
Started POST "/rooms/ieghuEJA3WfgXuXqdR8XEGMZrYJF2nwnnoOGGwt5OApDGXGpPZL6Y368AqonrcbtLxeWgXkH%2FD5eRam+cvgSTDh7wM2hFW4jqpnHoOw%2FRbDgnQNxn14y6h8GouQRDR4Kj+IMmA==/messages" for 153.203.168.240 at 2019-03-17 01:32:34 +0900
Cannot render console from 153.203.168.240! Allowed networks: 127.0.0.1, ::1, 127.0.0.0/127.255.255.255
(0.5ms) SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
? /root/.rbenv/versions/2.5.3/lib/ruby/gems/2.5.0/gems/activerecord-5.2.2.1/lib/active_record/log_subscriber.rb:98
Processing by MessagesController#create as HTML
Parameters: {"utf8"=>"?", "authenticity_token"=>"Rt2ek/0VX3TLN925qJkg7zYYlL3e7VUf6BF/mRsze5sVigmTjVzm6HcKz66RYuJCtjWl3T0Iv9qlQB47zf/f1w==", "message"=>{"name"=>"pryn", "content"=>"kokok"}, "commit"=>"Post", "room_url_token"=>"ieghuEJA3WfgXuXqdR8XEGMZrYJF2nwnnoOGGwt5OApDGXGpPZL6Y368AqonrcbtLxeWgXkH/D5eRam+cvgSTDh7wM2hFW4jqpnHoOw/RbDgnQNxn14y6h8GouQRDR4Kj+IMmA=="}
Room Load (0.4ms) SELECT "rooms".* FROM "rooms" WHERE "rooms"."url_token" IS NULL LIMIT [["LIMIT", 1]]
? app/controllers/messages_controller.rb:22
(0.2ms) BEGIN
? app/controllers/messages_controller.rb:7
Message Create (1.0ms) INSERT INTO "messages" ("name", "content", "room_id", "created_at", "updated_at") VALUES (, , , , ) RETURNING "id" [["name", "pryn"], ["content", "kokok"], ["room_id", 1], ["created_at", "2019-03-16 16:32:34.837275"], ["updated_at", "2019-03-16 16:32:34.837275"]]
? app/controllers/messages_controller.rb:7
(0.5ms) COMMIT
? app/controllers/messages_controller.rb:7
Redirected to
Completed 500 Internal Server Error in 40ms (ActiveRecord: 7.9ms)
ActionController::UrlGenerationError (No route matches {:action=>"show",
:controller=>"rooms", :url_token=>nil}, missing required keys:
[:url_token]):
在routes.rb
Rails.application.routes.draw do
resources :rooms, only: [:create, :new, :show], param: :url_token do
resources :messages, only: [:create]
end
end
根据你的路线:
room_messages POST /rooms/:room_url_token/messages(.:format)
这是发送给请求的 :room_url_token
参数,而不是 :url_token
。
您可以在此处查看日志:
Processing by MessagesController#create as HTML
Parameters: {"utf8"=> ... "room_url_token"=>"ieghuEJA3WfgXuXqdR8XEGMZrYJF2nwnnoOGGwt5OApDGXGpPZL6Y368AqonrcbtLxeWgXkH/D5eRam+cvgSTDh7wM2hFW4jqpnHoOw/RbDgnQNxn14y6h8GouQRDR4Kj+IMmA=="}
在您的 MessagesController
中,像这样修复 set_room
方法:
def set_room
@room = Room.find_by(url_token: params[:room_url_token])
end