Asocjacje

Witam, nie mogę poradzić sobie z asosjacjami, mam klasy

[code=‘ruby’]class FirmsController < ApplicationController
def index
@firms = Firm.all
end

def new
@firm = Firm.new
end

def create
@firm = Firm.new(params[:firm])
@firm.save
redirect_to :action => ‘index’
end

def destroy
@firm = Firm.find(params[:id])
@firm.destroy
redirect_to :action => ‘index’
end

end[/code]
oraz

[code=‘ruby’]class WorkersController < ApplicationController

def new
@firm = Firm.find(params[:firm_id])
@worker = @firm.workers.build
end

def create
@firm = Firm.find(params[:firm_id])
@worker = @firm.workers.build(params[:worker])
@worker.save
end
end[/code]

[code=‘ruby’]class Firm < ActiveRecord::Base
has_many :workers
end

class Worker < ActiveRecord::Base
belongs_to :firm
end[/code]
i niestety przy tworzeniu nowego pracownika dla danej firmy otrzymuję błąd, że nie może znaleźć firmy bez id… Co powinienem zrobić aby to działało ? szukałem już w necie ale nic nie mogę znaleźć co by mi pomogło. Pewnie większość tutoriali które czytałem są już nieaktualne i może też dla tego nie potrafię sobie z tym poradzić.

A jak wyglądają routy?

routy wyglądają tak

resources :firms resources :workers
i pewnie to jest przyczyną problemu ale nie wiedziałem, że je trzeba też jakoś specjalnie ustawiać

tak to jest przyczyną, też muszą mieć relacje (has_many => … ) to już wiesz co szukać i jak ;]

znalazłem coś takiego map.resources :firms, :has_many => :workers ale coś nie tak z tym map jest bo wywala błąd
undefined local variable or method `map’ for #ActionDispatch::Routing::Mapper:0x7b2e6c8

panie mieszasz pan kod z rails 2.3.x i rails 3
w trójce używasz

 resources :workers

w dwójce

 map.resources :workers

taka deklaracja resources :firms, :has_many => :workers nic nie zmienia, nadal mam błąd w którym wypisuje mi, że nie może odnaleźć firmy bez id

[quote=Cz4cha][code=‘ruby’]class WorkersController < ApplicationController

def new
@firm = Firm.find(params[:firm_id])
@worker = @firm.workers.build
end[/code]
[/quote]
Nie obrazisz się chyba jak spytam czy na pewno w parametrach przekazujesz :firm_id ?

Trzeba chyba prościej wyjaśnić:

  1. Musisz wygenerować ścieżkę w postaci:
    coś ala
    /firms/1/workers

ta liczba to twoj firm_id

jakie się generują, sprawdzić możesz poprzez

$ rake routes

Wtedy możesz ją w kontrolerze zczytać z parametrów, tak jak robisz.

W modelu musisz zmieć relację, masz ją więc spoko.

  1. W bazie danych musisz mieć pole które zapewni tą relację

Jak masz wszystko tak jak piszę to musi działać

W bazie danych dla tabeli workers mam kolumnę firm_id, robię wszystko tak jak jest na tej stronie http://www.apohllo.pl/guides/getting_started.html w punkcie 8, z jedną małą różnicą, link do tworzenia nowych pracowników mam w widoku firms/index.html.erb, jednak to przekazywanie parametru firm_id coś nie działa. Dodatkowo wywala mi błąd, że nie ma metody new_firm_worker_path(@firm), pewnie w railsach 3 już jest inaczej

Pokaż kod widoku formularza, który ma prowadzić do utworzenia pracownika

[code=‘ruby’]

New Worker

<% form_for([@firm, @worker]) do |f| %>

<%= f.label :Nazwa %>
<%= f.text_field :name %>

<%= f.label :Wiek %>
<%= f.text_field :age %>

<%= f.submit 'Utworz' %>

<% end %>

<%= link_to ‘Wroc’, firms_path %>[/code]
pewnie jest w nim coś nie tak, ale taki był właśnie w tym poradniku ;p

A czy twoje routy wyglądają tak?

resources :firms do resources :workers end

podam link do repozytorium na github, byłbym bardzo wdzięczny jeśli ktoś powie mi jak poprawić kod abym mógł dodawać pracowników z widoku firm

Sporo masz tam namieszane:

Poniżej to co powinno być by działało:

[code=ruby]class WorkersController < ApplicationController

def new
@firm = Firm.find(params[:firm_id])
@worker = @firm.workers.build
end

def create
@firm = Firm.find(params[:firm_id])
@worker = @firm.workers.build(params[:worker])
@worker.save
end

def destroy

end
end[/code]

[code=ruby]Zad2::Application.routes.draw do
resources :firms do
resources :workers
end

root :to => “firms#index”
end[/code]
Też masz w widokach namieszane:

  • wywal z public index.html
  • w plik index firm wywal naglowki html, body itp, masz to w layout
  • w linku do Usuń masz błąd, robisz tam petle więc z firm wywal @ z linku

To chyba tyle po tych poprawkach u mnie poszlo

Ten główny błąd był po tym, że w kontrolerze miałeś Firm.find(params[:id]), a to kontroler nie firm a Wokrek wiec id z linku dotyczy workera, a nie firmy, musisz tam dac firm_id, a nie id

u mnie ciągle wywala No route matches {:controller=>“workers”, :action=>“new”} sprawdziłeś czy po dodaniu jakiejś firmy ciągle działa ? bo to się wysypuje przez tą linię <%= link_to ‘Dodaj pracownika’, new_firm_worker_path(@firm) %> a póki nie ma żadnej firmy to ten kod tak jakby nie istnieje

<%= link_to 'Dodaj pracownika', new_firm_worker_path(firm) %>

teraz działa :wink: dzięki, wiedziałem, że jakiś mały błąd gdzieś się jeszcze ukrył