Rails 3中如何通过子控制器创建父模型? (属于协会)
我有两个资源:主题和帖子。 我试图弄清楚如何通过 Post 控制器创建一个主题。 模型如下所示:
class Topic < ActiveRecord::Base
has_many :posts, :dependent => :destroy
validates :name, :presence => true,
:length => { :maximum => 32 }
attr_accessible :name
end
class Post < ActiveRecord::Base
belongs_to :topic, :touch => true
has_many :comments, :dependent => :destroy
accepts_nested_attributes_for :topic
attr_accessible :name, :title, :content, :topic
end
posts/_form.html.erb:
<%= simple_form_for @post do |f| %>
<h1>Create a Post</h1>
<%= f.input :name, :label => false, :placeholder => "Name" %>
<%= f.input :title, :label => false, :placeholder => "Title" %>
<%= f.input :content, :label => false, :placeholder => "Content" %>
<%= f.input :topic, :label => false, :placeholder => "Topic" %>
<%= f.button :submit, "Post" %>
<% end %>
posts_controller.rb#create:
def create
@post = Post.new(params[:topic])
respond_to do |format|
if @post.save
format.html { redirect_to(@post, :notice => 'Post was successfully created.') }
else
format.html { render :action => "new" }
end
end
end
使用 posts/_form.html.erb 我可以创建帖子,但不会随之创建关联的主题。谁能告诉我为什么会出现这种行为以及如何纠正它?我正在使用 Ruby 1.9.2、Rails 3.0.7 和 simple_form gem。
I have two resources: Topics and Posts.
I am trying to figure out how I can create a Topic through the Post controller.
The models look like this:
class Topic < ActiveRecord::Base
has_many :posts, :dependent => :destroy
validates :name, :presence => true,
:length => { :maximum => 32 }
attr_accessible :name
end
class Post < ActiveRecord::Base
belongs_to :topic, :touch => true
has_many :comments, :dependent => :destroy
accepts_nested_attributes_for :topic
attr_accessible :name, :title, :content, :topic
end
posts/_form.html.erb:
<%= simple_form_for @post do |f| %>
<h1>Create a Post</h1>
<%= f.input :name, :label => false, :placeholder => "Name" %>
<%= f.input :title, :label => false, :placeholder => "Title" %>
<%= f.input :content, :label => false, :placeholder => "Content" %>
<%= f.input :topic, :label => false, :placeholder => "Topic" %>
<%= f.button :submit, "Post" %>
<% end %>
posts_controller.rb#create:
def create
@post = Post.new(params[:topic])
respond_to do |format|
if @post.save
format.html { redirect_to(@post, :notice => 'Post was successfully created.') }
else
format.html { render :action => "new" }
end
end
end
With posts/_form.html.erb I can create posts, but an associated topic is not created along with it. Can anyone tell me why I get this behavior and possibly how to correct it? I'm using Ruby 1.9.2, Rails 3.0.7 and the simple_form gem.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
Railscasts 有几个关于这个问题的剧集。
第16集(需订阅)
源代码:
https://github.com/railscasts/016-virtual-attributes-revised
还有这一集
http://railscasts.com/episodes/57-create-model-through -text-field
views/products/_form.rhtml
models/product.rb
我认为 Ryan 在类别上的解决方案比 @nathanvda 的选项 1 更优雅。因为它在模型而不是控制器中处理数据。如果您需要在不同的控制器/操作中执行相同的工作,您将看到好处。
Railscasts has several episodes about this problem.
episode 16(subscription needed)
Source code:
https://github.com/railscasts/016-virtual-attributes-revised
And this episode
http://railscasts.com/episodes/57-create-model-through-text-field
views/products/_form.rhtml
models/product.rb
I think Ryan's solution on category is more elegant than @nathanvda 's option 1. As it deal the data in Model instead of Controller. If you need to do same work in different controllers/actions, you will see the benefits.
根据你想做什么,我可以看到两种选择。
选项 1:使用文本框创建或查找现有主题(如您所用)。在你的控制器中你可以写这样的东西:
这是快速而肮脏的方式。对于您输入的每个
主题
,它将尝试按名称查找该主题,或者创建它并分配它。但是,这很容易出错。如果您的主题集有限,还有一种更简单的方法。选项 2:使用选择框,即可用主题的列表。在您的视图中写入:
这将呈现一个包含可能主题的选择框。在您的控制器中,您只需编写:
虽然第二个选项非常简单,但动态添加主题却不太容易。您可以使用自动完成字段在两者之间执行某些操作,该字段将允许查找值(如果存在)或添加新值(如果不存在)。
希望这有帮助。
Depending on what you want to do, i can see two options.
Option 1: Use a text-box to create or find an existing topic (as you had). In your controller you would write something like:
That is the quick and dirty way. It will, for each
topic
you type, try to find that topic, by name, or create it and assign it. But, this is error-prone. If your sets of topics is limited, there is a much easier way.Option 2: use a select-box, a list of available topics. In your view write:
That will render a select-box with the possible topics. And in your controller you just have to write:
While this second option is really easy, it is less easy to add topics on the fly. You could do something in between, using an autocomplete field, that will either allow looking up values if they exist, or add new values if they don exist.
Hope this helps.
您是否在服务器日志中收到批量分配错误?您可能需要将 :topic_attributes 添加到 attr_accessible 列表中。
Are you getting mass assignment errors in the server log? You may need to add :topic_attributes to your attr_accessible list.