我有这个应用程序,我正在尝试使用谱系表添加狗家庭关系(狗A是狗B的兄弟姐妹)。但是我在制作能够实现这一目标的形式时遇到问题。 This is how my form looks like at the moment.
正如您可以看到表单在狗配置文件页面中加载,用户可以选择他的一只狗并创建关系。这是来自views / pedigrees / _form.html.erb的views / dog / show.html.erb页面中呈现的表单代码:
<%= form_for(@pedigree, url: new_pedigree_path, html: {method: :post}) do |d| %>
Select your dog:
<%= d.collection_select(:dog_id, @dogs,:id, :dname, :prompt => "Select your dog") %>
<br>
Select your dog relation to the dog from this profile:
<%= select_tag(:relation_name, options_for_select([['Sibling', 1], ['Parent', 2], ['Grandparent', 3],
['Great-grandparent', 4], ['Child', 5], ['Grandchild', 6], ['Great-grandchild', 7]])) %>
<br>
<%= d.submit 'Add Relation' %>
<% end %>
我在生成的源代码中获得的内容如下:
<form class="new_pedigree" id="new_pedigree" action="/pedigree/new" accept-charset="UTF-8" method="post"><input name="utf8" type="hidden" value="✓" /><input type="hidden" name="authenticity_token" value="RYOjO10gUvVUQkRaqyum8wB0VJrTwm8MQ6WxIJ3eM4ukP2zHHDECFaT8UUYytSv2OGBUGhvK4k3fwOt+xDfabA==" />
当我点击按钮提交表单时,我收到以下错误:
Missing template pedigree/new, application/new with...
如何操作form_for以便在不需要新表单模板的情况下呈现谱系关系?如何在按下提交按钮时调用#create方法?感谢。
答案 0 :(得分:1)
为了避免对"/pedigrees"
网址进行硬编码,您的表单部分中的第一行应为
<%= form_for(@pedigree, url: pedigrees_path, html: {method: :post}) do |d| %>
您需要了解new
和create
操作(及其关联的路径/路径/网址)之间的区别。 new_pedigree_path
不是您想要实际创建新记录时使用的路径。 (new_pedigree_path
仅用于获取表单。)相反,实际创建新谱系是通过对pedigrees_path
的POST请求完成的。
Controller Action HTTP Verb Path Helper Path
Get a form
for making a new GET new_pedigree_path /new_pedigree
new relationship
Send data about
the new relationship create POST pedigrees_path /pedigrees
to the server; create
the new record.
答案 1 :(得分:1)
因为看起来你是新手,所以让我添加一些背景信息。
您目前正在dogs#show
页面上调用该表单。这不意味着您必须对url
进行硬编码 - 传递@pedigree
变量应该为Rails提供将表单提交到pedigrees#create
所需的信息:
<%= form_for @pedigree do |d| %>
Select your dog:
<%= d.collection_select :dog_id, @dogs,:id, :dname, prompt: "Select your dog" %>
Select your dog relation to the dog from this profile:
<%= select_tag(:relation_name, options_for_select [['Sibling', 1], ['Parent', 2], ['Grandparent', 3],
['Great-grandparent', 4], ['Child', 5], ['Grandchild', 6], ['Great-grandchild', 7]]) %>
<%= d.submit 'Add Relation' %>
<% end %>
如果您设置了@pedigree
变量,则应将表单发送到pedigrees#create
或pedigrees#update
(具体取决于您是使用Pedigree.new
设置变量还是Pedigree.find
)。
由于您通过部分调用表单,我高度建议仅使用 local 变量:
#app/controllers/dogs_controller.rb
class DogsController < ApplicationController
def show
@dog = Dog.find params[:id]
@pedigree = ...
end
end
#app/views/dogs/show.html.erb
<%= render "pedigrees/form", locals: {pedigree: @pedigree} %>
#app/views/pedigrees/_form.html.erb
<%= form_for pedigree ...
这可能看起来效率低下,但是您必须记住,partials可以在您的应用中的任何位置使用。在其中使用@instance_variables
实际上是antipattern的一半!
其他一些说明:
<强> 1。切勿使用HTML进行“样式化”
我看到有人使用<br>
和<p>
在HTML中创建换行符。
虽然这“有效”,但这不正确。事实上,它是彻头彻尾的破坏性(特别是当您使用更大的应用程序时)。
HTML 应视为标记(格式仅); CSS是样式所需要的:
<%= form_for @pedigree do |d| %>
<%= d.text_field :name %>
<%= d.text_field :type %>
<% end %>
这就是HTML的外观,然后您可以使用following CSS to style it:
#app/assets/stylesheets/application.css
form input {
display: block;
margin: 3px 0;
}
如果出于正当理由需要换行(也许你正在使用列表或其他东西),那么请务必使用<br>
- 但绝不要用它来创建边距/填充的错觉。< / p>
除此之外,它将使用响应式界面等方式破坏您的样式。
-
<强> 2。许多对多强>
我不知道您的Rails级别,如果这对您来说过于简单,请道歉。
如果你使用many-to-many
关系,我相信你可以大规模改善这一点,特别是has_many :through
:
#app/models/dog.rb
class Dog < ActiveRecord::Base
has_many :pedigrees
has_many :relations, through: :pedigrees
end
#app/models/pedigree.rb
class Pedigree < ActiveRecord::Base
belongs_to :dog
belongs_to :relation
end
#app/models/relation.rb
class Relation < ActiveRecord::Base
has_many :pedigrees
has_many :dogs, through: :pedigrees
end
这样您就可以通过一次通话填充@dog.pedigrees
或@dog.relations
。因此,您无需使用create
/ edit
新的“血统”记录,而只需使用dog
:
#app/controllers/dogs_controller.rb
class DogsController < ApplicationController
def show
@dog = Dog.find params[:id]
end
def update
end
private
def dog_params
params.require(:dog).permit(:name, :relation_ids)
end
end
这将允许您使用以下内容:
#app/views/dogs/show.html.erb
<%= form_for @dog do |f| %>
<%= f.text_field :name %>
<%= f.collection_select :relation_ids, Relation.all, :id, :name %>
<%= f.submit %>
<% end %>
这应该允许您选择您的狗拥有的各种“关系”,自动创建Pedigree
条记录。
答案 2 :(得分:0)
我能够通过以下方式解决这个问题:
我必须硬编码form_for
<%= form_for(@pedigree, url: "/pedigrees", html: {method: :post}) do |d| %>
我的路线文件中也出错了。而不是资源:谱系y有资源:血统。