简体   繁体   English

Rails路线-URL切换父ID和子ID

[英]Rails Routes - URL switches parent and child ids

I'm having trouble with my routes. 我的路线有问题。 I want my user to be able to edit a guitar that they've added. 我希望我的用户能够编辑他们添加的吉他。 I have two problems: 我有两个问题:

1.The url for the edit guitar view is incorrect. 1.编辑吉他视图的URL不正确。 The IDs of the user and guitar are switched and I'm not sure why http://localhost:3000/users/23/guitars/26/edit The 23 is the guitar id and the 26 is the user id. 用户和吉他的ID已切换,我不确定为什么http://localhost:3000/users/23/guitars/26/edit 23是吉他ID,而26是用户ID。

2.When a user is able to update a guitar, it updates all the guitars. 2.当用户能够更新吉他时,它会更新所有吉他。 I'm not sure why this is happening either. 我也不知道为什么会这样。

I've spent some time trying to fix this but can't figure it out. 我花了一些时间尝试解决此问题,但无法解决。 Here's the relevant code: 以下是相关代码:

My routes: 我的路线:

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 Rails路线

Guitar model: 吉他型号:

class Guitar < ApplicationRecord
  belongs_to :user
  has_many :transactions, dependent: :destroy
end

User model: 用户模型:

class User < ApplicationRecord
 has_many :guitars, dependent: :destroy
 has_many :transactions, dependent: :destroy
 belongs_to :registration
end

Guitar Controller: 吉他控制器:

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 to edit guitar: 链接以编辑吉他:

 <% @guitars.each do |guitar|%>
  <p> <%= guitar.brand %> </p>
  <p><%= link_to 'Edit guitar', edit_user_guitar_path(guitar) %></p>
 <% end %>

Edit guitar view: 编辑吉他视图:

<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 %>

There are a couple of problems with the above - in your controller code: 上面有几个问题-在您的控制器代码中:

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

You're only ever referencing params[:id] , but the user id will be coming in under the nested route as :user_id , so the User.find should be User.find(params[:user_id]) . 您只引用过params[:id] ,但是用户ID将作为:user_id进入嵌套路由,因此User.find应该是User.find(params[:user_id])

I'd also point out that unless you want users to edit other users guitars, I'd personally do away with the user_id being in the route at all, and instead just use current_user , assuming that's something that is exposed by your authorization setup: 我还要指出,除非您希望用户编辑其他用户的吉他,否则我个人会完全放弃user_id ,而是只使用current_user ,这是您的授权设置所公开的:

def edit
  @guitar = current_user.guitars.find(params[:id])
end

Otherwise, someone could potentially guess a user_id and then an id for a guitar belonging to that user, and edit it. 否则,某人可能会猜测一个user_id ,然后猜测一个属于该用户的吉他的id ,然后对其进行编辑。

The other issue is if you do keep your nested route, then your link code will need updating: 另一个问题是,如果您保留嵌套路由,则您的链接代码将需要更新:

<p><%= link_to 'Edit guitar', edit_user_guitar_path(guitar) %></p>

As you have a nested route, you need to specify all of the parts of the route, in order - in this case, user, then guitar: 当您拥有嵌套路线时,您需要按顺序指定路线的所有部分-在这种情况下,请先指定用户,再指定吉他:

<p><%= link_to 'Edit guitar', edit_user_guitar_path(guitar.user, guitar) %></p>

As I mentioned though, this highlights how the nested route is a little redundant if users can only edit their own guitars. 正如我所提到的,这突显了如果用户只能编辑自己的吉他,则嵌套路线会有些多余。

Hope that helps! 希望有帮助!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM