我在显示资源字段的任何视图时遇到问题。我有这种关联:用户有一个农场,农场有很多领域。
我的模特:
User.rb
has_one :farm
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable,
:token_authenticatable, :confirmable, :lockable, :timeoutable
attr_accessible :email, :password, :password_confirmation, :remember_me, :username
--
Farm.rb
belongs_to :user
has_many :fields
attr_accessible :name, :contact, :adress, :user_id
--
Field.rb
belongs_to :farm
attr_accessible :crop, :longitude, :latitude, :occupied, :farm_id
我的佣金路线:
user_farm_fields GET /users/:user_id/farm/:farm_id/fields(.:format)
{:action=>"index", :controller=>"fields"}
POST /users/:user_id/farm/:farm_id/fields(.:format)
{:action=>"create", :controller=>"fields"}
new_user_farm_field GET /users/:user_id/farm/:farm_id/fields/new(.:format) {:action=>"new", :controller=>"fields"}
edit_user_farm_field GET /users/:user_id/farm/:farm_id/fields/:id/edit(.:format){:action=>"edit", :controller=>"fields"}
user_farm_field GET /users/:user_id/farm/:farm_id/fields/:id(.:format) {:action=>"show", :controller=>"fields"}
PUT /users/:user_id/farm/:farm_id/fields/:id(.:format) {:action=>"update", :controller=>"fields"}
DELETE /users/:user_id/farm/:farm_id/fields/:id(.:format) {:action=>"destroy", :controller=>"fields"}
user_farms GET /users/:user_id/farm(.:format)
{:action=>"index", :controller=>"farms"}
POST /users/:user_id/farm(.:format)
{:action=>"create", :controller=>"farms"}
new_user_farm GET /users/:user_id/farm/new(.:format)
{:action=>"new", :controller=>"farms"}
edit_user_farm GET /users/:user_id/farm/:id/edit(.:format)
{:action=>"edit", :controller=>"farms"}
user_farm GET /users/:user_id/farm/:id(.:format)
{:action=>"show", :controller=>"farms"}
PUT /users/:user_id/farm/:id(.:format)
{:action=>"update", :controller=>"farms"}
DELETE /users/:user_id/farm/:id(.:format)
{:action=>"destroy", :controller=>"farms"}
users GET /users(.:format)
{:action=>"index", :controller=>"users"}
POST /users(.:format)
{:action=>"create", :controller=>"users"}
new_user GET /users/new(.:format)
{:action=>"new", :controller=>"users"}
edit_user GET /users/:id/edit(.:format)
{:action=>"edit", :controller=>"users"}
user GET /users/:id(.:format)
{:action=>"show", :controller=>"users"}
PUT /users/:id(.:format)
{:action=>"update", :controller=>"users"}
DELETE /users/:id(.:format)
{:action=>"destroy", :controller=>"users"}
new_user_session GET /accounts/sign_in(.:format)
{:action=>"new", :controller=>"devise/sessions"}
user_session POST /accounts/sign_in(.:format)
{:action=>"create", :controller=>"devise/sessions"}
destroy_user_session GET /accounts/sign_out(.:format)
{:action=>"destroy", :controller=>"devise/sessions"}
user_password POST /accounts/password(.:format)
{:action=>"create", :controller=>"devise/passwords"}
new_user_password GET /accounts/password/new(.:format)
{:action=>"new", :controller=>"devise/passwords"}
edit_user_password GET /accounts/password/edit(.:format)
{:action=>"edit", :controller=>"devise/passwords"}
PUT /accounts/password(.:format)
{:action=>"update", :controller=>"devise/passwords"}
cancel_user_registration GET /accounts/cancel(.:format)
{:action=>"cancel", :controller=>"devise/registrations"}
user_registration POST /accounts(.:format)
{:action=>"create", :controller=>"devise/registrations"}
new_user_registration GET /accounts/sign_up(.:format)
{:action=>"new", :controller=>"devise/registrations"}
edit_user_registration GET /accounts/edit(.:format)
{:action=>"edit", :controller=>"devise/registrations"}
PUT /accounts(.:format)
{:action=>"update", :controller=>"devise/registrations"}
DELETE /accounts(.:format)
{:action=>"destroy", :controller=>"devise/registrations"}
user_confirmation POST /accounts/confirmation(.:format)
{:action=>"create", :controller=>"devise/confirmations"}
new_user_confirmation GET /accounts/confirmation/new(.:format)
{:action=>"new", :controller=>"devise/confirmations"}
GET /accounts/confirmation(.:format)
{:action=>"show", :controller=>"devise/confirmations"}
user_unlock POST /accounts/unlock(.:format)
{:action=>"create", :controller=>"devise/unlocks"}
new_user_unlock GET /accounts/unlock/new(.:format)
{:action=>"new", :controller=>"devise/unlocks"}
GET /accounts/unlock(.:format)
{:action=>"show", :controller=>"devise/unlocks"}
home_index GET /home/index(.:format)
{:controller=>"home", :action=>"index"}
root /
{:controller=>"home", :action=>"index"}
我的新表格形式:
<%= form_for([@user, @farm, @field]) do |f| %>
<% if @field.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(@field.errors.count, "error") %> prohibited this field from being saved:</h2>
<ul>
<% @field.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :crop %><br />
<%= f.text_field :crop %>
</div>
<div class="field">
<%= f.label :longitude %><br />
<%= f.text_field :longitude %>
</div>
<div class="field">
<%= f.label :latitude %><br />
<%= f.text_field :latitude %>
</div>
<div class="field">
<%= f.label :occupied %><br />
<%= f.check_box :occupied %>
</div>
<div class="field">
<%= f.label :description %><br />
<%= f.text_area :description %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
我相应的新方法:
def new
@farm = Farm.where("user_id = ?", current_user).first
@user = current_user
@field = Field.new
respond_to do |format|
format.html # new.html.erb
format.json { render json: @field }
end
我的routes.rb:
resources :users do
resources :farms, :path => 'farm' do
resources :fields
end
end
devise_for :users, :path => 'accounts'
在我尝试使用此链接创建新字段后:
<%= link_to 'New Field', new_user_farm_field_path(@user, @farm, @field) %>
我收到此消息:
undefined method `user_fields_path' for #<#<Class:0x496e1b0>:0x496b6d8>
答案 0 :(得分:0)
在表面层面,问题可能与form_for
帮助程序在没有正确嵌套结构时尝试为表单设置url
有关
您可以尝试这样做:
#app/views/fields/new.html.erb
<%= form_for [@user, @farm, @field], url: user_farm_fields_path do |f| %> #-> the create path
-
<强>嵌套强>
可能会有一些deeper issues:
相应的路线助手是publisher_magazine_photo_url, 要求您在所有三个级别指定对象。的确,这个 情况令人困惑,这是Jamis Buck的一篇热门文章 为好的Rails设计提出了一个经验法则:
资源不应该嵌套超过1级。
这里需要注意的是,文档规定你可以做你正在做的事情(深度嵌套)(我原本以为你不应该这样做)。无论如何,我认为你可能会考虑让你的路线更加“浅”,以确保它们更易于管理。
为此,我希望您考虑user
在您所做的事情中的作用:
User has_one Farm
这意味着当您致电resources :farms
时,您已获得antipattern - 如果用户只有一个农场,您如何选择农场?当然,更好的方法是删除对用户的任何依赖,创建singular resource for :farm
,然后像以前一样设置fields
流
以下是我的表现:
#config/routes.rb
root "farms#index"
resources :farms, only: :index
resource :farm do #-> domain.com/farm (authentictable)
resources :fields #-> domain.com/farm/fields/new
end
#app/controllers/farms_controller.rb
Class FarmsController < ApplicationController
before_action :authenticate_user!, except: :index
def show
@farm = current_user.farm
end
def index
@farms = Farm.all
end
end
#app/models/user.rb
Class User < ActiveRecord::Base
has_one :farm
before_create :build_farm #-> creates farm if not already built
end
这使您能够连接到current_user
:
#app/views/fields/new.html.erb
<%= form_for [@farm, @field] do |f| %>
<%= f.text_area :field_name %>
<%= f.submit %>
<% end %>
#app/controllers/fields_controller.rb
Class FieldsController < ApplicationController
before_action :authenticate_user!
def new
@farm = current_user.farm
@field = @farm.fields.new
end
def create
@farm = current_user.farm
@field = @farm.fields.new field_params
end
private
def field_params
params.require(:field).permit(:field_name)
end
end