我的3个模型遵循线性结构。董事会有许多主题。主题有很多帖子。
我的模型如下所示:
app / models / board.rb
class Board < ActiveRecord::Base
has_many :topics
...
end
app / models / topic.rb
class Topic < ActiveRecord::Base
belongs_to :user
belongs_to :board
has_many :posts
validates :title, presence: true, length: { maximum: 255 }
validates :user_id, presence: true
validates :board_id, presence: true
# Temporary holder for new topic content
attr_accessor :content
...
end
app / models / post.rb
class Post < ActiveRecord::Base
belongs_to :user
belongs_to :topic
validates :user_id, presence: true
validates :topic_id, presence: true
validates :content, length: { minimum: 8 }
end
app / views / topic / new.html.erb
<h1>Create new topic</h1>
Return to <%= link_to @board.title, @board %>
<div>
<%= form_for(:topic) do |f| %>
<%= render 'shared/error_messages', object: @topic %>
<%= f.label :title %>
<%= f.text_field :title %>
<%= f.fields_for(:posts) do |p| %>
<%= p.label :content %>
<%= p.text_area :content %>
<% end %>
<%= f.submit "Post new topic", class: "button submit" %>
<% end %>
</div>
当我创建一个新主题时,topics_controller#create操作的一部分工作就是使用用户提供的内容创建一个Post。现在,如果帖子未能保存,我最终要做的就是删除主题。
app / controllers / topics_controller.rb
def create
@board = Board.find(params[:id])
# Here, topic_params are just the strong parameters for Topic
@topic = @board.topics.build(topic_params.merge({user_id: current_user.id}))
# Blank post for the view
@post = Post.new
if @topic.save
post_content = {content: params[:topic][:content], user_id: current_user.id}
@post = @topic.posts.build(post_content)
if @post.save
flash[:success] = "Topic created"
redirect_to @topic
else
@topic.delete
render 'new'
end
else
render 'new'
end
end
我想不出任何其他方法来完成此操作,而无需更改模型上的验证。为了使@post有效,它必须具有topic_id。因此,@ topic必须已成功保存。但是,如果@topic有效并保存,但@post不保存,那么我不希望@topic保留在数据库中。如果只创建@topic和@post或都不创建它们,则是更可取的。
您应该使用rails accepts_nested_attributes
。设置模型
class Board < ActiveRecord::Base
has_many :topics
...
end
class Topic < ActiveRecord::Base
belongs_to :user
belongs_to :board
has_many :posts
accepts_nested_attributes_for :posts
...
end
您的表格:
<%= form_for @topic do |f| %>
// topic fields
<%= f.fields_for @post do |p| %>
// post fields
<% end %>
<%= f.button :submit, :class => "button", value: 'Submit' %>
<% end %>
您的控制器
def new
@board = Board.find(params[:id])
@topic = @board.topics.build
@post= @topic.posts.build
end
def create
@board = Board.find(params[:id])
@topic = @board.topics.build(topic_params)
if @topic.save # you are only checking for topic if you post is not saved then your topic will also wont save and you wont have to delete anything
redirect_to @topic
else
render "new"
end
end
private
def topic_params
params.require(:topic).permit(:id, :attribute, posts_attributes: [:title])
end
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句