ruby-on-rails - Rails 找不到没有 ID 的用户
问题描述
嗨,我有一个使用设计为我的用户身份验证的 rails 5 应用程序。
该应用程序有一个属于用户的农场模型。用户登录并被带到 farm#index 页面。
在农场索引页面上,我们显示 current_user.farm.all 和一个按钮,以使用 @user 创建一个新农场。用户通过 before_action :authenticate_user 进行身份验证!
当我去创建一个新农场时,我得到
ActiveRecord::RecordNotFound in FarmsController#new
Couldn't find User without an ID
应用程序/视图/农场/index.html.erb
<div class="row">
<div class="col-sm-6">
<h1>Farms</h1>
</div>
<div class="col-sm-6 text-right">
<%= link_to new_farm_path(@user), class: 'btn btn-primary' do %>
Add New Farm
<% end %>
</div>
</div>
<div class="table-responsive">
<table class="table table-striped table-bordered table-hover">
<thead>
<tr>
<th>Address</th>
<th></th>
</tr>
</thead>
<tbody>
<% @farms.each do |farm| %>
<%= content_tag :tr, id: dom_id(farm), class: dom_class(farm) do %>
<td><%= farm.address %></td>
<td><%= link_to 'Show', farm %></td>
<% end %>
<% end %>
</tbody>
</table>
</div>
应用程序/控制器/farms_controller.rb
class FarmsController < ApplicationController
before_action :authenticate_user!
before_action :set_farm, only: [:show, :edit, :update, :destroy]
# GET /farms
# GET /farms.json
def index
@farms = current_user.farms.all
end
# GET /farms/1
# GET /farms/1.json
def show
end
# GET /farms/new
def new
@user = User.find(params[:user_id])
@farm = Farm.new
end
# GET /farms/1/edit
def edit
end
# POST /farms
# POST /farms.json
def create
@user = User.find(params[:user_id])
@farm = Farm.new(farm_params)
@farm.user = @user
respond_to do |format|
if @farm.save
format.html { redirect_to @farm, notice: 'Farm was successfully created.' }
format.json { render :show, status: :created, location: @farm }
else
format.html { render :new }
format.json { render json: @farm.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /farms/1
# PATCH/PUT /farms/1.json
def update
respond_to do |format|
if @farm.update(farm_params)
format.html { redirect_to @farm, notice: 'Farm was successfully updated.' }
format.json { render :show, status: :ok, location: @farm }
else
format.html { render :edit }
format.json { render json: @farm.errors, status: :unprocessable_entity }
end
end
end
# DELETE /farms/1
# DELETE /farms/1.json
def destroy
@farm.destroy
respond_to do |format|
format.html { redirect_to farms_url, notice: 'Farm was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_farm
@farm = Farm.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def farm_params
params.require(:farm).permit(:address, :user_id)
end
end
路线
Rails.application.routes.draw do
resources :farms, shallow: true do
resources :paddocks, shallow: true do
resources :crops, shallow: true
resources :treatments, shallow: true do
resources :ingredients, shallow:true
end
end
end
resources :ingredients, only: [:index, :show]
resources :treatments, only: [:index, :show]
namespace :admin do
resources :users
resources :announcements
resources :notifications
resources :services
root to: "users#index"
end
get '/privacy', to: 'home#privacy'
get '/terms', to: 'home#terms'
resources :notifications, only: [:index]
resources :announcements, only: [:index]
authenticate :user, lambda { |u| u.admin? } do
mount Sidekiq::Web => '/sidekiq'
end
devise_for :users, controllers: { omniauth_callbacks: "users/omniauth_callbacks" }
root to: 'home#index'
# For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
end
应用程序/模型/farm.rb
class Farm < ApplicationRecord
belongs_to :user
has_many :paddocks
end
应用程序/模型/user.rb
class User < ApplicationRecord
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :masqueradable, :database_authenticatable, :registerable, :recoverable, :rememberable, :validatable, :omniauthable
has_person_name
has_many :notifications, foreign_key: :recipient_id
has_many :services
has_many :farms
end
应用程序/视图/农场/_form.html.erb
<%= form_for [@user, @farm] do |form| %>
<div class="form-group">
<%= form.label :address %>
<%= form.text_field :address, class: 'form-control' %>
</div>
<div class="form-group">
<%= form.submit class: 'btn btn-primary' %>
</div>
<% end %>
解决方案
您的FarmsController
new/create 和您的农场表单 ( form_for [@user, @farm] do |form|
) 是为嵌套路由定义的,用户如下:
resources :users, shallow: true do
resources :farms, shallow: true do
#...
end
end
在存在的地方生成路径:user_id
:
user_farms GET /users/:user_id/farms(.:format) farms#index
POST /users/:user_id/farms(.:format) farms#create
new_user_farm GET /users/:user_id/farms/new(.:format) farms#new
要解决您的问题,请将 添加resources :users
到嵌套路由并更改link_to
农场索引视图内部:
<%= link_to new_user_farm_path(@user), class: 'btn btn-primary' do %>
另一种解决方案:
如果始终为您创建农场,current_user
您可以更改@user = User.find(params[:user_id])
为@user = current_user
new/create 并修复如下形式:
form_for @farm do |form| do
#...
end
您不必以这种方式更改路线。
推荐阅读
- javascript - 如何修复该调用函数 getMoney
- hive - Hive 上的多个左外连接
- android - 如果从一个片段移动到另一个片段,则在发布版本中显示汉堡图标代替后退图标
- ios - 以足够的宽度显示 UILabel 的文本
- excel - 如何从 VBA selenium webdriver 中的日期选择器中选择日期
- php - 在从 html 表单获取的日期之间使用 php 从 mysql 中选择数据,但日期存储在日、月、年下的 3 个不同列中
- system-verilog - SystemVerilog 断言:使用两个时钟
- python - 增加 XGBClassifier 中少数类的召回率
- c# - Entity Framework 6 fluent api删除n:n关系上的级联
- javascript - 在 Internet Explorer 中的 svg 上使用 AppendChild 是错误的