Rails 路由 - URL 切换父子 ID
Rails Routes - URL switches parent and child ids
我的路线有问题。我希望我的用户能够编辑他们添加的吉他。我有两个问题:
1.The url 编辑吉他视图不正确。用户ID和吉他ID调换了不知道为什么http://localhost:3000/users/23/guitars/26/edit
23是吉他id,26是用户id。
2.When 用户可以更新一把吉他,它会更新所有吉他。我也不确定为什么会这样。
我花了一些时间试图解决这个问题,但无法解决。这是相关代码:
我的路线:
Rails.application.routes.draw do
devise_for :registrations
root to: 'pages#home'
resources :users, only: [ :show, :new, :create, :edit, :update, :destroy ] do
resources :guitars, only: [ :edit, :update ]
end
resources :guitars, only: [ :show, :new, :create, :destroy ]
# For details on the DSL available within this file, see
http://guides.rubyonrails.org/routing.html
end
Rails Routes
吉他型号:
class Guitar < ApplicationRecord
belongs_to :user
has_many :transactions, dependent: :destroy
end
用户模型:
class User < ApplicationRecord
has_many :guitars, dependent: :destroy
has_many :transactions, dependent: :destroy
belongs_to :registration
end
吉他控制器:
def edit
@user = User.find(params[:id])
@guitar = @user.guitars.find(params[:id])
end
def update
@guitar = Guitar.find(params[:id].to_i)
@guitar = Guitar.update(guitar_params)
if @guitar
redirect_to user_path(current_user)
else
render :new
end
end
private
def guitar_params
params.require(:guitar).permit(:brand, :model, :condition, :finish, :year,
:description, :price)
end
Link 编辑吉他:
<% @guitars.each do |guitar|%>
<p> <%= guitar.brand %> </p>
<p><%= link_to 'Edit guitar', edit_user_guitar_path(guitar) %></p>
<% end %>
编辑吉他视图:
<h1>Edit your guitar</h1>
<%= simple_form_for @guitar do |f| %>
<%= f.error_notification %>
<%= f.input :brand, required: true, autofocus: true, input_html: {value: 'brand'} %>
<%= f.input :model, required: true, autofocus: true, input_html: {value: 'model'} %>
<%= f.input :condition, required: true, autofocus: true, input_html: {value: 'condition'} %>
<%= f.input :finish, required: true, autofocus: true, input_html: {value: 'finish'} %>
<%= f.input :year, required: true, autofocus: true, input_html: {value: 'year'} %>
<%= f.input :description, required: true, autofocus: true, input_html: {value: 'description'} %>
<%= f.input :price, required: true, autofocus: true, input_html: {value: 'price'} %>
<%= f.button :submit, :class => "btn btn-primary" %>
<% end %>
上面有几个问题 - 在您的控制器代码中:
def edit
@user = User.find(params[:id])
@guitar = @user.guitars.find(params[:id])
end
def update
@guitar = Guitar.find(params[:id].to_i)
@guitar = Guitar.update(guitar_params)
if @guitar
redirect_to user_path(current_user)
else
render :new
end
end
您只引用了 params[:id]
,但用户 ID 将作为 :user_id
进入嵌套路由,因此 User.find
应该是 User.find(params[:user_id])
.
我还要指出,除非您希望用户编辑其他用户的吉他,否则我个人会完全取消路由中的 user_id
,而只是使用 current_user
,假设这是您的授权设置公开的内容:
def edit
@guitar = current_user.guitars.find(params[:id])
end
否则,有人可能会猜测属于该用户的吉他 user_id
,然后是 id
,然后进行编辑。
另一个问题是,如果您保留嵌套路线,那么您的 link 代码将需要更新:
<p><%= link_to 'Edit guitar', edit_user_guitar_path(guitar) %></p>
由于您有嵌套路线,因此您需要按顺序指定路线的所有部分 - 在本例中,用户,然后是吉他:
<p><%= link_to 'Edit guitar', edit_user_guitar_path(guitar.user, guitar) %></p>
正如我所提到的,这突出了如果用户只能编辑自己的吉他,那么嵌套路线是多么的多余。
希望对您有所帮助!
我的路线有问题。我希望我的用户能够编辑他们添加的吉他。我有两个问题:
1.The url 编辑吉他视图不正确。用户ID和吉他ID调换了不知道为什么http://localhost:3000/users/23/guitars/26/edit
23是吉他id,26是用户id。
2.When 用户可以更新一把吉他,它会更新所有吉他。我也不确定为什么会这样。
我花了一些时间试图解决这个问题,但无法解决。这是相关代码:
我的路线:
Rails.application.routes.draw do
devise_for :registrations
root to: 'pages#home'
resources :users, only: [ :show, :new, :create, :edit, :update, :destroy ] do
resources :guitars, only: [ :edit, :update ]
end
resources :guitars, only: [ :show, :new, :create, :destroy ]
# For details on the DSL available within this file, see
http://guides.rubyonrails.org/routing.html
end
Rails Routes
吉他型号:
class Guitar < ApplicationRecord
belongs_to :user
has_many :transactions, dependent: :destroy
end
用户模型:
class User < ApplicationRecord
has_many :guitars, dependent: :destroy
has_many :transactions, dependent: :destroy
belongs_to :registration
end
吉他控制器:
def edit
@user = User.find(params[:id])
@guitar = @user.guitars.find(params[:id])
end
def update
@guitar = Guitar.find(params[:id].to_i)
@guitar = Guitar.update(guitar_params)
if @guitar
redirect_to user_path(current_user)
else
render :new
end
end
private
def guitar_params
params.require(:guitar).permit(:brand, :model, :condition, :finish, :year,
:description, :price)
end
Link 编辑吉他:
<% @guitars.each do |guitar|%>
<p> <%= guitar.brand %> </p>
<p><%= link_to 'Edit guitar', edit_user_guitar_path(guitar) %></p>
<% end %>
编辑吉他视图:
<h1>Edit your guitar</h1>
<%= simple_form_for @guitar do |f| %>
<%= f.error_notification %>
<%= f.input :brand, required: true, autofocus: true, input_html: {value: 'brand'} %>
<%= f.input :model, required: true, autofocus: true, input_html: {value: 'model'} %>
<%= f.input :condition, required: true, autofocus: true, input_html: {value: 'condition'} %>
<%= f.input :finish, required: true, autofocus: true, input_html: {value: 'finish'} %>
<%= f.input :year, required: true, autofocus: true, input_html: {value: 'year'} %>
<%= f.input :description, required: true, autofocus: true, input_html: {value: 'description'} %>
<%= f.input :price, required: true, autofocus: true, input_html: {value: 'price'} %>
<%= f.button :submit, :class => "btn btn-primary" %>
<% end %>
上面有几个问题 - 在您的控制器代码中:
def edit
@user = User.find(params[:id])
@guitar = @user.guitars.find(params[:id])
end
def update
@guitar = Guitar.find(params[:id].to_i)
@guitar = Guitar.update(guitar_params)
if @guitar
redirect_to user_path(current_user)
else
render :new
end
end
您只引用了 params[:id]
,但用户 ID 将作为 :user_id
进入嵌套路由,因此 User.find
应该是 User.find(params[:user_id])
.
我还要指出,除非您希望用户编辑其他用户的吉他,否则我个人会完全取消路由中的 user_id
,而只是使用 current_user
,假设这是您的授权设置公开的内容:
def edit
@guitar = current_user.guitars.find(params[:id])
end
否则,有人可能会猜测属于该用户的吉他 user_id
,然后是 id
,然后进行编辑。
另一个问题是,如果您保留嵌套路线,那么您的 link 代码将需要更新:
<p><%= link_to 'Edit guitar', edit_user_guitar_path(guitar) %></p>
由于您有嵌套路线,因此您需要按顺序指定路线的所有部分 - 在本例中,用户,然后是吉他:
<p><%= link_to 'Edit guitar', edit_user_guitar_path(guitar.user, guitar) %></p>
正如我所提到的,这突出了如果用户只能编辑自己的吉他,那么嵌套路线是多么的多余。
希望对您有所帮助!