【问题标题】:No route matches {:action=>"show", :controller=>"shops", :id=>nil}, missing required keys: [:id]没有路线匹配 {:action=>"show", :controller=>"shops", :id=>nil},缺少必需的键:[:id]
【发布时间】:2019-06-30 12:03:17
【问题描述】:

我正在构建一个电子商务应用,每个用户都可以在其中创建自己的商店。用户和商店之间的关联应该是

user has_one shop
shop belongs_to user

到目前为止,创建商店的用户运行良好。但是对于那些没有的人,它显示了一个错误:

No route matches {:action=>"show", :controller=>"shops", :id=>nil},  missing required keys: [:id]

在我的shops_controller.rb

class ShopsController < ApplicationController
  before_action :find_shop, only: [:show, :edit, :update, :destroy]
  before_action :authenticate_user!
  before_action :find_user

  def show
    if current_user.shop.blank?
        render 'new'
    else
        @items = Item.where(shop_id: @shop.id)   
    end
  end

  def index    
    @shops = Shop.all.order("created at DESC")    
  end

  def new
    @shop = current_user.build_shop
  end

  def create 
    @shop = current_user.build_shop(shop_params)
    if @shop.save
        session[:shop_id] = @shop.id
       flash[:success] = "Creating item success"
       redirect_to @shop, notice: 'success'
    else
        render 'new'
    end
  end

private 

  def shop_params
    params.require(:shop).permit( :name , :user_id)
  end

  def find_store
    @shop = Shop.find(params[:id])
  end

  def find_user
    @user = UrStore.find_by(params[:user_id])
  end
end

application.html.erb

 <% if user_signed_in?%>
   <%= link_to "profile", user_path(current_user.id) %>
   <% if current_user.shop == nil %>
     <li><%= link_to "Your shop", new_shop_path %></li>
   <% else %>
     <li><%= link_to "Your shop", shop_path(current_user.shop.id)%></li>    
   <% end %>   
 <% end %>

current_user 由 gem 'devise' 自动生成。

当我点击“你的商店”时发生错误,并且该错误只发生在没有创建他/她的商店的用户身上

在 routes.rb 中:

devise_for :users
root 'static_pages#home'
as :user do
  get "signin" => "devise/sessions#new"
  post "signin" => "devise/sessions#create"
  delete "signout" => "devise/sessions#destroy"
end
resources :shops

这行引发了错误:

<li><%= link_to "Your Shop",shop_path(current_user.shop.id)%></li>

我正在寻找解决这个问题的方法:-)

【问题讨论】:

  • 您在哪里点击以引发此错误?
  • 让我编辑问题
  • 你能给我们看看你的routes.rb文件吗?
  • 抱歉让您久等了,我更新了我的问题
  • 看起来没有错误,我们可以有完整的错误跟踪吗?它应该指向特定的行。

标签: ruby-on-rails ruby


【解决方案1】:

当您转到new_shop_path 时,您的控制器操作new 似乎建立了一个用户商店:

@shop = current_user.build_shop

所以从这里current_user.shop != nil

但是由于当时没有保存,所以本店没有id。因此,在您看来,它位于 else 中,因为 shop 不是 nil 但没有 id 并且会引发错误。

<% if current_user.shop == nil %>
  <li><%= link_to "Your shop", new_shop_path %></li>
<% else %>
  <li><%= link_to "Your shop", shop_path(current_user.shop.id)%></li>    
<% end %>   

改成:

<% if !current_user.shop || !current_user.shop.id %>
  <li><%= link_to "Your shop", new_shop_path %></li>
<% else %>
  <li><%= link_to "Your shop", shop_path(current_user.shop.id)%></li>    
<% end %>   

【讨论】:

  • 它应该是current_user.shop&amp;.new_record?,它负责处理未定义的错误。
【解决方案2】:

我认为您想要重定向而不是渲染,并确保商店被持久化到数据库中。

def show
  if current_user.shop&.persisted?
    redirect_to :new
  else
    @items = Item.where(shop_id: @shop.id)   
  end
end

在您看来,您也可以使用安全导航来执行此操作并使用.persisted?,因为您更关心shop.id,并且这种逻辑比其他方式更有意义。

<% if current_user.shop&.persisted? %>
  <li><%= link_to "Your shop", shop_path(current_user.shop.id)%></li>
<% else %>
  <li><%= link_to "Your shop", new_shop_path %></li>
<% end %> 

【讨论】:

  • 我尝试了redirect_to,但仍然是同样的错误
  • 查看基于上一个答案的更新答案。两者都应该可以帮助您并使您的代码更具可读性。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-11-26
  • 2016-12-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多