4

如何在rails中使用多個表繼承來構建對象的嵌套表單?我正在嘗試使用has_many關係的模型創建一個嵌套窗體,以創建一個具有多表繼承功能的另一組模型。我使用formtasticcocoon作爲嵌套格式,並使用act_as_relation gem來實現多表繼承。具有多個表繼承的嵌套表格

我有以下型號:

class Product < ActiveRecord::Base 
acts_as_superclass 
belongs_to :store 
end 

class Book < ActiveRecord::Base 
    acts_as :product, :as => :producible 
end 

class Pen < ActiveRecord::Base 
    acts_as :product, :as => :producible acts_as :product, :as => :producible 
end 

class Store < ActiveRecord::Base 
    has_many :products 
    accepts_nested_attributes_for :products, :allow_destroy => true, :reject_if => :all_blank 
end' 

在這個例子中,只有獨特的屬性,本書與其他產品相比是一個作者字段。實際上,我有很多獨特的書籍屬性,這就是爲什麼我選擇多表繼承而不是普通單表繼承的原因。

我想創建一個嵌套的表單,允許您創建一個新的商店與產品。這是我的形式:

<%= semantic_form_for @store do |f| %> 
    <%= f.inputs do %> 
    <%= f.input :name %> 

    <h3>Books/h3> 
    <div id='books'> 
    <%= f.semantic_fields_for :books do |book| %> 
     <%= render 'book_fields', :f => book %> 
    <% end %> 
      <div class='links'> 
     <%= link_to_add_association 'add book', f, :books %> 
     </div> 

    <% end %> 
<%= f.actions :submit %> 
<% end %> 

而且book_fields部分:

<div class='nested-fields'> 
    <%= f.inputs do %> 
    <%= f.input :author %> 
    <%= link_to_remove_association "remove book", f %> 
    <% end %> 
</div> 

我得到這個錯誤:

undefined method `new_record?' for nil:NilClass 

基於閱讀GitHub的頁面上的問題進行act_as_relation,我想到了使商店和書籍之間的關係更加明確:

class Product < ActiveRecord::Base 
acts_as_superclass 
belongs_to :store 
has_one :book 
accepts_nested_attributes_for :book, :allow_destroy => true, :reject_if => :all_blank 
end 

class Book < ActiveRecord::Base 
    belongs_to :store 
    acts_as :product, :as => :producible 
end 

class Store < ActiveRecord::Base 
     has_many :products 
     has_many :books, :through => :products 
     accepts_nested_attributes_for :products, :allow_destroy => true, :reject_if => :all_blank 
     accepts_nested_attributes_for :books, :allow_destroy => true, :reject_if => :all_blank 
    end 

現在,我收到一個無聲的錯誤。我可以使用表格創建新的商店,並且繭讓我可以添加新的書籍字段,但是當我提交商店時,會創建而不是子書。當我瀏覽`/書籍/新書'路線時,我可以創建一個新的書籍記錄,它可以毫無問題地跨越(產品和書籍表)。

是否有解決此問題的方法?其餘代碼可以在here找到。

+0

你檢查params哈希表,看看孩子的書屬性是否正確包含? –

回答

2

也許你可以:

  • 手動構建本本關係上的stores_controller#new行動

    @store.books.build

  • 商店手動你關係stores_controller#create行動

    @store.books ...(不是真的對如何實現它充滿信心)

保持我們的發佈。

+0

根據您的想法在控制器中手動執行更多操作,現在我正在嘗試使用create_assocation方法,但該方法似乎不會自動通過元編程附加。 – sutee

+1

我終於明白了。一旦我清理了一些並確定了我需要做的最低數量的更改以使其工作,我會發布解決方案。由於您的答案與最終解決方案最接近,因此我會獎勵您的賞金。謝謝! – sutee

+0

抱歉,無法回覆您的評論...繁忙的一週。請務必發佈解決方案並接受它,以便將問題標記爲已回答。很高興我能幫上忙。 – rlecaro2

1

您可能想要考慮創建自己的表單對象。這是一個RailsCast PRO視頻,但這裏有一些在ASCIIcast例子:

def new 
    @signup_form = SignupForm.new(current_user) 
end 

此註冊表單可以包括關係到其他物體,就像你在你原來的控制器代碼:

class SignupForm 
    # Rails 4: include ActiveModel::Model 
    extend ActiveModel::Naming 
    include ActiveModel::Conversion 
    include ActiveModel::Validations 

    validates_presence_of :username 
    validates_uniqueness_of :username 
    validates_format_of :email, with: /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/ 
    validates_length_of :password, minimum: 6 

    def persisted? 
    false 
    end 

    def subscribed 
    subscribed_at 
    end 

    def subscribed=(checkbox) 
    subscribed_at = Time.zone.now if checkbox == "1" 
    end 

    def generate_token 
    begin 
     self.token = SecureRandom.hex 
    end while User.exists?(token: token) 
    end 
end 

這裏是RailsCast的鏈接。獲得專業會員資格可能值得你花時間。我已經越來越幸運通過www.codeschool.com會員,您可以得到「大獎」,當你完成的課程:

RailsCast: http://railscasts.com/episodes/416-form-objects