嗨,我有一个使用devise进行用户身份验证的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
app / views / farms / 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>
app / controllers / 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
app / models / farm.rb
class Farm < ApplicationRecord
belongs_to :user
has_many :paddocks
end
app / models / 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
app / views / farms / _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 %>
答案 0 :(得分:1)
您的FarmsController
新建/创建和您的服务器场表单(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
创建服务器场,则可以在new / create中将@user = User.find(params[:user_id])
更改为@user = current_user
并修复如下形式:
form_for @farm do |form| do
#...
end
您不必以此方式更改路线。