2014-04-23 165 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