2013-06-26 30 views
7

Mam 3 modele: cytat, klient i przedmiot. Każda oferta zawiera jednego klienta i jeden przedmiot. Chciałbym stworzyć nową wycenę, nowego klienta i nowy element w odpowiednich tabelach po naciśnięciu przycisku przesyłania. Przyjrzałem się innym pytaniom i railscastom i albo one nie działają w mojej sytuacji, albo nie wiem, jak je wdrożyć.Ruby on Rails: tworzenie rekordów dla wielu modeli za pomocą jednego formularza i jednego przesyłania

quote.rb

class Quote < ActiveRecord::Base 
    attr_accessible :quote_number 
    has_one :customer 
    has_one :item 
end 

customer.rb

class Customer < ActiveRecord::Base 
    attr_accessible :firstname, :lastname 
    #unsure of what to put here 
    #a customer can have multiple quotes, so would i use has_many or belongs_to? 
    belongs_to :quote 
end 

item.rb

class Item < ActiveRecord::Base 
    attr_accessible :name, :description 
    #also unsure about this 
    #each item can also be in multiple quotes 
    belongs_to :quote 

quotes_controller.rb

class QuotesController < ApplicationController 
    def index 
    @quote = Quote.new 
    @customer = Customer.new 
    @item = item.new 
    end 

    def create 
    @quote = Quote.new(params[:quote]) 
    @quote.save 
    @customer = Customer.new(params[:customer]) 
    @customer.save 
    @item = Item.new(params[:item]) 
    @item.save 
    end 
end 

items_controller.rb

class ItemsController < ApplicationController 
    def index 
    end 

    def new 
    @item = Item.new 
    end 

    def create 
    @item = Item.new(params[:item]) 
    @item.save 
    end 
end 

customers_controller.rb

class CustomersController < ApplicationController 
    def index 
    end 

    def new 
    @customer = Customer.new 
    end 

    def create 
    @customer = Customer.new(params[:customer]) 
    @customer.save 
    end 
end 

moja forma cytatów/new.html.erb

<%= form_for @quote do |f| %> 
    <%= f.fields_for @customer do |builder| %> 
    <%= label_tag :firstname %> 
    <%= builder.text_field :firstname %> 
    <%= label_tag :lastname %> 
    <%= builder.text_field :lastname %> 
    <% end %> 
    <%= f.fields_for @item do |builder| %> 
    <%= label_tag :name %> 
    <%= builder.text_field :name %> 
    <%= label_tag :description %> 
    <%= builder.text_field :description %> 
    <% end %> 
    <%= label_tag :quote_number %> 
    <%= f.text_field :quote_number %> 
    <%= f.submit %> 
<% end %> 

gdy próbuję twierdząc, że pojawia się błąd:

Can't mass-assign protected attributes: item, customer 

Tak, aby spróbować go naprawić zaktualizowałem attr_accessible w quote.rb zawierać: przedmiot,: klient, ale potem dostaję ten błąd:

Item(#) expected, got ActiveSupport::HashWithIndifferentAccess(#) 

Każda pomoc będzie mile widziana.

+0

Spróbuj utworzyć: imię i nazwisko: dostęp do opisu i: imię i nazwisko dostępne w odpowiednich modelach. – lilwupster

+0

@lilwupster Zrobiłem to, ale nadal mam te same błędy. – notblakeshelton

Odpowiedz

4

Aby przesłać formularz, a jest to związane z nimi dzieci trzeba użyć accepts_nested_attributes_for

Aby to zrobić, trzeba zadeklarować w modelu sterownika masz zamiar użyć (w Twoim przypadku, to wygląda Cytat Controller.

class Quote < ActiveRecord::Base 
    attr_accessible :quote_number 
    has_one :customer 
    has_one :item 
    accepts_nested_attributes_for :customers, :items 
end 

Ponadto, należy upewnić się, że deklarują który attributes are accessible więc uniknąć błędów innych masowych przypisania.

+0

welp, umieszczam accepts_nested_attributes_for: customers,: items, a także wypróbowałem: customer,: item, ale nic nie zadziałało. – notblakeshelton

+0

Czy sprawdziłeś, czy atrybuty są dostępne (powyższy link)? – creativereason

+0

Tak, próbowałem tego; to nie zadziałało, więc poszedłem z attr_protected: id na wszystkich z nich, aby upewnić się, że nie pominąłem żadnego, ale teraz wypluwa błąd "ActiveRecord :: AssociationTypeMismatch w QuotesController # create
Artykuł (oczekiwany), ale ActiveSupport :: HashWithIndifferentAccess (#)” – notblakeshelton

1

Jeśli chcesz dodać info dla modeli zmierzających proponuję zastosować nested_model_form li ke to odniesienie: http://railscasts.com/episodes/196-nested-model-form-part-1?view=asciicast.

To rozwiązanie jest bardzo proste i najczystsze.

+0

Czy muszę w ogóle zmienić moje pliki modeli? Ten screencast używa relacji has_many, belongs_to, podczas gdy używam has_one i has_many, ale nie mam pojęcia, czy to prawda. Próbowałem zmienić moje "@" w moich zmiennych w index.html.erb na ":", ale nie zadziałało. – notblakeshelton