Rails Routes - URL切换父级和子级ID

时间:2018-01-13 17:52:44

标签: ruby-on-rails routes nested-routes

我的路线遇到了麻烦。我希望我的用户能够编辑他们添加的吉他。我有两个问题:

1.编辑吉他视图的网址不正确。切换了用户和吉他的ID,我不确定为什么http://localhost:3000/users/23/guitars/26/edit 23是吉他id,26是用户ID。

2.当用户能够更新吉他时,它会更新所有吉他。我不确定为什么会发生这种情况。

我花了一些时间来解决这个问题,但无法弄明白。这是相关的代码:

我的路线:

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

链接编辑吉他:

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

1 个答案:

答案 0 :(得分:1)

上面有一些问题 - 在您的控制器代码中:

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])。< / p>

我还要指出,除非您希望用户编辑其他用户吉他,否则我个人会完全取消user_id在路线中,而只是使用current_user,假设您的授权设置暴露了某些内容:

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

否则,某人可能会猜到user_id然后id来判断属于该用户的吉他,然后进行编辑。

另一个问题是如果你保留了嵌套路线,那么你的链接代码将需要更新:

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

由于您有嵌套路线,您需要按顺序指定路线的所有部分 - 在本例中为用户,然后是吉他:

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

正如我所提到的,这突出了如果用户只能编辑自己的吉他,嵌套路线如何有点多余。

希望有所帮助!