2014-04-23 131 views
1

我想建立一个CRUD控制器和表单内的3 STI模型的Rails 3Rails的嵌套形式

class Publication < ActiveRecord::Base 

    has_many :posts 

end 

,其中帖子是STI模型:

class Post < ActiveRecord::Based 
    attr_accessible :title, :description 
end 

和我有几个遗传模型:

class Image < Post 
end 

class Video < Post 
end 

class Status < Post 
end 

我想为出版物创建一个CRUD,用户可以根据需要添加尽可能多的帖子,为任何类型的帖子动态添加嵌套表单。

有没有我可以使用的支持STI的这种嵌套形式的宝石?

我试图建立一个表单,但我需要修改Publication类并为每个附加的继承模型引入嵌套属性。有没有办法避免这样做?

class Publication < ActiveRecord::Base 

    has_many :videos, :dependent => :destroy 
    accepts_nested_attributes_for :videos, allow_destroy: true 
    attr_accessible :videos_attributes 

    has_many :posts 

end 

回答

2

我写了一个简短的博客文章关于这个问题:http://www.powpark.com/blog/programming/2014/05/07/rails_nested_forms_for_single_table_inheritance_associations

我基本上决定使用cocoon宝石,它提供了两个辅助方法 - link_to_add_associationlink_to_remove_association,其动态添加相应的装饰类字段的形式(如PostImageVideo

# _form.html.haml 

= simple_form_for @publication, :html => { :multipart => true } do |f| 

    = f.simple_fields_for :items do |item| 
    = render 'item_fields', :f => item 
    = link_to_add_association 'Add a Post', f, :items, :wrap_object => Proc.new { |item| item = Item.new } 
    = link_to_add_association 'Add an Image', f, :items, :wrap_object => Proc.new { |item| item = Image.new } 
    = link_to_add_association 'Add a Video', f, :items, :wrap_object => Proc.new { |item| item = Video.new } 

    = f.button :submit, :disable_with => 'Please wait ...', :class => "btn btn-primary", :value => 'Save' 

:wrap_object PROC生成正确的对象,到内部呈现_item_fields部分,如:

# _item_fields.html.haml 

- if f.object.type == 'Video' 
    = render 'video_fields', :f => f 
- elsif f.object.type == 'Image' 
    = render 'image_fields', :f => f 
- elsif f.object.type == 'Post' 
    = render 'post_fields', :f => f 
2

你可以简单地这样做。

在出版物控制器

class PublicationsController < ApplicationController 
    def new 
     @publication = Publication.new 
     @publication.build_post 
    end 
end 

您的模型应该是这样的

class Publication < ActiveRecord::Base 
    has_many :posts, dependent: :destroy 
    accepts_nested_attributes_for :posts  
end 

class Post < ActiveRecord::Base 
    belongs_to :publication 
    Post_options = ["Image", "Video", "Status"] 
end 

在您的形式

<%= form_for(@publication) do |f| %> 
    <p> 
    <%= f.label :title %><br> 
    <%= f.text_field :title %> 
    </p> 

    <p> 
    <%= f.label :description %><br> 
    <%= f.text_area :description %> 
    </p> 

    <%= f.fields_for :post do |p| %> 
     <%= p.label :post_type %> 
     <%= p.select(:post_type, Post::Post_options , {:prompt => "Select"}, {class: "post"}) %> 
    <% end %> 
    <p> 
    <%= f.submit %> 
    </p> 
<% end %> 

注:你应该有一个post_type属性您Post模型来得到这个工作。

+0

谢谢你的回答,帕万,但这不是我所需要的。我找到了解决问题的办法,并且很快就会发布答案。欲了解更多信息,你可以看看https://github.com/nathanvda/cocoon/issues/210 –

+0

@antonevangelatov好吧,无论如何高兴的帮助:) – Pavan