Ruby on rails 4 具有嵌套属性和嵌套表单的rails 4
我正在尝试为我的第一个rails 4项目建模,以实现从教程到现实世界的飞跃 该应用程序是一个马展注册 用户装置添加一个“条目”。 条目可以由一个或多个“骑乘”组成 每个骑乘可以有一个“马”和一个“骑手”嵌套表单,允许用户在创建新条目时选择现有的马和骑手或通过表单创建新的马和骑手。 我开始使用Cocoon和Formtastic制作一些嵌套的web表单: buy I在将相关数据保存到表时遇到问题 当我保存条目时,rides表包含以下各项的正确值: 测试,输入id,但不是马id 条目表没有行驶id值。它只有我在控制器中手动设置的用户id 我的问题是: 我确信我遗漏了一些概念性的概念,但是我是否正确地设置了模型关联? 如何编辑当前表单以正确保存数据 当我在控制器中调试时,我得到一个看起来很奇怪的参数值: {utf8=>√, 真实性\u令牌=>XXXXXXXXXXXXX=,条目=>{show\u date=>2014年10月26日,骑乘属性=>{1407930343404=>{test=>Intro B,horses=>{name=>Plain Horse,\u destroy=>}},commit=>Create条目,action=>Create,controller=>entries} 我想我会在“骑乘属性”散列中看到“马属性”,但我看到的只是“马” 任何澄清,包括与示例的链接,都将受到欢迎Ruby on rails 4 具有嵌套属性和嵌套表单的rails 4,ruby-on-rails-4,nested-forms,nested-attributes,Ruby On Rails 4,Nested Forms,Nested Attributes,我正在尝试为我的第一个rails 4项目建模,以实现从教程到现实世界的飞跃 该应用程序是一个马展注册 用户装置添加一个“条目”。 条目可以由一个或多个“骑乘”组成 每个骑乘可以有一个“马”和一个“骑手”嵌套表单,允许用户在创建新条目时选择现有的马和骑手或通过表单创建新的马和骑手。 我开始使用Cocoon和Formtastic制作一些嵌套的web表单: buy I在将相关数据保存到表时遇到问题 当我保存条目时,rides表包含以下各项的正确值: 测试,输入id,但不是马id 条目表没有行驶id值
class User < ActiveRecord::Base
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
has_many :entries
has_many :rides, :through => :entries
has_many :horses, :through => :entries
has_many :riders, :through => :entries
end
class Entry < ActiveRecord::Base
belongs_to :user
has_many :rides, :dependent => :destroy
has_many :horses, :through => :rides
has_many :riders, :through => :rides
accepts_nested_attributes_for :rides, :allow_destroy => true
accepts_nested_attributes_for :horses
accepts_nested_attributes_for :riders
end
class Ride < ActiveRecord::Base
belongs_to :entry
belongs_to :user
has_one :horse #, :dependent => :destroy
has_one :rider
accepts_nested_attributes_for :horse
accepts_nested_attributes_for :rider
end
class Horse < ActiveRecord::Base
belongs_to :ride # :dependent => :destroy
belongs_to :user, :dependent => :destroy
end
class Rider < ActiveRecord::Base
#belongs_to :ride #, :dependent => :destroy
belongs_to :user, :dependent => :destroy
has_many :rides
end
部分进入控制器:
def new
@user=current_user
@entry=Entry.new
end
def create
@entry = Entry.new(entry_params)
@entry.user_id=current_user[:id]
respond_to do |format|
if @entry.save
# example of params value
# {"utf8"=>"√", "authenticity_token"=>"xxxxxxxxxxxxxx=", "entry"=>{"show_date"=>"10/26/2014", "rides_attributes"=>{"1407930343404"=>{"test"=>"Intro B", "horses"=>{"name"=>"Plain Horse", "_destroy"=>""}}}}, "commit"=>"Create Entry", "action"=>"create", "controller"=>"entries"}
debugger
format.html { redirect_to @entry, notice: 'Entry was successfully created.' }
format.json { render :show, status: :created, location: @entry }
else
format.html { render :new }
format.json { render json: @entry.errors, status: :unprocessable_entity }
end
end
end
def entry_params
# added ids based on comments below
params.require(:entry).permit(:show_date, rides_attributes: [:id, :test, :_destroy, horses_attributes: [:name, :id]] )
end
观点:
_form.html.haml
= semantic_form_for @entry do |f|
= f.inputs do
= f.label :show_date, "Show Date"
= f.input :show_date, :as => :select, :collection => [['08/03/2014', '08/03/2014'], ['09/14/2014', '09/14/2014'], ['10/26/2014', '10/26/2014'], ['11/15/2014', '11/15/2014']]
%h3 Rides
#rides
= f.semantic_fields_for :rides do |ride|
= render 'ride_fields', :f => ride
.links
= link_to_add_association 'add ride', f, :rides
= f.actions do
= f.action :submit
.nested-fields
= f.inputs do
= f.label :test, "Test"
= f.input :test, :as => :select, :collection => [['Intro A', 'Intro A'], ['Intro B', 'Intro B'], ['Intro C', 'Intro C']]
= f.semantic_fields_for :horses do |horse|
= render 'horse_fields', :f => horse
= link_to_add_association 'add horse', f, :horse
.nested-fields
=f.inputs do
= f.input :name
.links
= link_to_add_association 'add horse', f, :horse
_ride_fields.html.haml
= semantic_form_for @entry do |f|
= f.inputs do
= f.label :show_date, "Show Date"
= f.input :show_date, :as => :select, :collection => [['08/03/2014', '08/03/2014'], ['09/14/2014', '09/14/2014'], ['10/26/2014', '10/26/2014'], ['11/15/2014', '11/15/2014']]
%h3 Rides
#rides
= f.semantic_fields_for :rides do |ride|
= render 'ride_fields', :f => ride
.links
= link_to_add_association 'add ride', f, :rides
= f.actions do
= f.action :submit
.nested-fields
= f.inputs do
= f.label :test, "Test"
= f.input :test, :as => :select, :collection => [['Intro A', 'Intro A'], ['Intro B', 'Intro B'], ['Intro C', 'Intro C']]
= f.semantic_fields_for :horses do |horse|
= render 'horse_fields', :f => horse
= link_to_add_association 'add horse', f, :horse
.nested-fields
=f.inputs do
= f.input :name
.links
= link_to_add_association 'add horse', f, :horse
_horse_fields.html.haml
= semantic_form_for @entry do |f|
= f.inputs do
= f.label :show_date, "Show Date"
= f.input :show_date, :as => :select, :collection => [['08/03/2014', '08/03/2014'], ['09/14/2014', '09/14/2014'], ['10/26/2014', '10/26/2014'], ['11/15/2014', '11/15/2014']]
%h3 Rides
#rides
= f.semantic_fields_for :rides do |ride|
= render 'ride_fields', :f => ride
.links
= link_to_add_association 'add ride', f, :rides
= f.actions do
= f.action :submit
.nested-fields
= f.inputs do
= f.label :test, "Test"
= f.input :test, :as => :select, :collection => [['Intro A', 'Intro A'], ['Intro B', 'Intro B'], ['Intro C', 'Intro C']]
= f.semantic_fields_for :horses do |horse|
= render 'horse_fields', :f => horse
= link_to_add_association 'add horse', f, :horse
.nested-fields
=f.inputs do
= f.input :name
.links
= link_to_add_association 'add horse', f, :horse
这就是我认为正在发生的事情,你把马安置在骑乘设施中,而不是进入。Ride接受has_one-horse关系的嵌套属性,因此您可以看到“horses”。如果您针对具有has\u many关系的条目提交了horses\u属性 在_form.html.haml的本节中,您将ride分配给了f 然后在你的_ride_fields.html.haml中,你用这个f来创建一个嵌套的表单,这个表单是在骑乘变量ride有一匹马的情况下创建的
= f.semantic_fields_for :horses do |horse|
= render 'horse_fields', :f => horse
因为您的骑乘模型接受了马的\u嵌套的\u属性\u,您在骑乘中看到了马。要查看马的属性,您需要根据接受马的嵌套属性的条目创建马
我相信您可以通过更改渲染来修复此问题,如条目模型表单中的此过程:
= render 'ride_fields', :f => ride, :e => f
然后马从f到e的嵌套形式如下:
使用嵌套属性时,传递到表单_的符号必须与关联名称匹配。你在干什么
f.semantic_fields_for :horses
但是骑乘没有马协会,只有马协会。由于这个原因,rails根本没有意识到您试图使用嵌套属性,这就是为什么数据嵌套在关键的horses而不是horses\u属性下。当然,您需要更改允许的参数以匹配
此外,如果一次骑行实际上只有一匹马,你不需要所有的东西来管理增加额外的马场。如果这是一个错误,那么请不要使用表单,而是更改模型,以便骑乘具有多个:马并接受:马的嵌套属性。我现在使用下面的代码正确保存关系,但需要注意一点。感谢以前的海报让我朝着正确的方向前进 还有Formtastic文档链接: 警告:如果我不想添加一匹新的马,我无法用表单select来选择一匹现有的马。添加新的马很好。 当我尝试使用当前注释的代码时,我得到错误: 未定义骑乘的骑乘方法id 我不确定这是否是一个formtastic问题、模型相关问题或控制器问题。如果我不明白的话,我会把它作为一个单独的问题发布 我在我最初的帖子中意识到,我不应该将外键(如ride_id)保存到“entries”表中,因为它们被保存到entry_id字段中的相关表中 控制器部分条目:
class EntriesController < ApplicationController
before_filter :set_horses, :except => [:destroy, :index]
def new
@c_user=current_user[:id]
@user=current_user
@entry = current_user.entries.new
@horses = current_user.horses
end
def create
@entry = current_user.entries.new(entry_params)
respond_to do |format|
if @entry.save
format.html { redirect_to @entry, notice: 'Entry was successfully created.' }
format.json { render :show, status: :created, location: @entry }
else
format.html { render :new }
format.json { render json: @entry.errors, status: :unprocessable_entity }
end
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_horses
if current_user.admin?
@horses=Horse.all
else
@horses = current_user.horses
end
end
# Never trust parameters from the scary internet, only allow the white list through.
def entry_params
params.require(:entry).permit(:show_date, rides_attributes: [:id, :test, :_destroy, horse_attributes: [:name, :id]] )
end
end
_ride_fields.html.haml
= semantic_form_for @entry do |f|
= f.inputs do
= f.input :show_date, :as => :select, :collection => ['2014/08/03', '2014/09/14', '2014/10/26', '2014/11/15']
%h3 Rides
#rides
= f.semantic_fields_for :rides do |ride|
= render 'ride_fields', :f => ride
.links
= link_to_add_association 'add ride', f, :rides
= f.actions do
= f.action :submit
.nested-fields
= f.inputs do
= f.label :test, "Test"
= f.input :test, :as => :select, :collection => [['Intro A', 'Intro A'], ['Intro B', 'Intro B'], ['Intro C', 'Intro C']]
= if !@horses.empty?
-# both of next 2 lines give error: undefined method ride_id for <Ride:0x00000008cc3370>
-#= f.input :horse, :as => :select, :collection => @horses
-#= f.input :horse, :as => :select, :member_label => :name
= f.semantic_fields_for :horse do |horse|
= render 'horse_fields', :f => horse
.links
= link_to_add_association 'add new horse', f, :horse
.nested-fields
= f.inputs do
= f.input :name
您可以显示参数白名单方法吗?像entry_params..我尝试了一些变体,包括horses而不是horses_属性。params.require:entry.permit:show_date,rides_attributes:[:test,:\u destroy,horses_attributes:[:name]]您总是通过每个嵌套资源的:id我添加了id:params.require:entry.permit:show_date,rides_attributes:[:id,:test,:\u destroy,horses:[:name,:id]]但我仍然没有在表中设置密钥id:未在条目表等中设置show_date。我的参数现在看起来如下:{utf8=>√, 真实性\u令牌=>XXXXXXXXXXXXXXXXXX=,条目=>{show\u date=>2014年11月15日,骑乘属性=>{1408016228347=>{test=>Intro C,horses=>{name=>Testy2,\u destroy=>}}},commit=>Create条目,action=>Create,controller=>entries}这给了我一个错误:未定义的局部变量或行的方法“e:=e.semantic\u字段:horses do | horse |
_如果我注释掉行:=link_to_add_association'add ride',f,:rides in _form.html.haml,那么我就失去了添加骑乘的能力,但在之前的注释中没有出现错误。我在_ride_fields.html.haml中将行更改为=f.semantic_fields_for:horse do | horse,但我仍然需要实际选择和/或添加一匹马。当我把马换成单数时,这种选择就消失了。我希望用户选择与他们相关的现有马,或者在需要时添加一匹新马,而无需转到单独的表单。我已经在骑乘模型中说明了很多:马,但我改变了,因为只有一匹给定的马可以进行特定的骑乘。