Sklep - koszyk

Witam
Próbuje napisać sklep, dotarłem do momentu w którym próbuje utworzyć koszyk.

Mam trzy modele:
Produckt > nazwa, opis produktu,
Option > nawa opcji np.: “Kolor”
Suboption > “biały, czerwony…”.

Całość zarządzam jednym formularzem za pomocą accepts_nested_attributes_for + javascript. Na stronie produktu subopcje wyświetlam za pomocą Select.

Co chciałbym osiągnąć?
Na stronie produktu przycisk “Dodaj do koszyka”, który zapisze nie tylko id produktu ale także wybrane przez klienta subopcje, w dodatku w momencie przejścia do koszyka chciałbym by klient miał możliwość ponownej edycji subopcji danego produktu, ponieważ opcje produktu będą dość poważnie rozbudowane.

Myślę żeby utworzyć nowy model, nie będzie on powiązany z bazą danych (zamówień nie zamierzam trzymać w bazie, od razu polecą emailem) i w nim będę trzymać obiekty z koszyka, id produktu, id opcji i powiązanej z nią id subopcji. Czy to sensowy kierunek?
Póki co walczę z przyciskiem, ale zwątpiłem czy ten kierunek mam sens, czy nie wymyślono sensowniejszego rozwiązania.

Generalnie zobacz jak to jest rozwiązane w Spree (spreecommerce.com).

Bardzo, bardzo zły pomysł. Od technicznego przez administracyjne (zmiany w zamówieniach, zwroty) po księgowe (raporty sprzedaży).

Z tymi zamówieniami, to trochę przesadziłem, chodzi o wycenę, nie będzie cen na stronie, zamiany zamówienia i zwroty nie wchodzą w rachubę, nie będzie nawet możliwości zakładania kont przez użytkowników. Może niepotrzebnie napisałem “sklep” bo to de fakto sklepem nie będzie, bardziej pierwszy krok w kontakcie z klientem, zapytanie ofertowe ze strony a później kontakt osobisty.

Maile mogą zginąć w transporcie. Dlaczego nie chcesz zamówień trzymać w bazie? To ułatwia wiele spraw - robisz zwyczajną edycję zwyczajnych modeli.

Aktualnie zrobiłem tak że na stronie produktu mam formularz którego Submit przekierowuje do akcji w której obrabiam sobie tablice params i całość planuje trzymać w sesji, dodając kolejne pozycje i na podstawie tego zbudować formularz podsumowania “zamówienia”.

Może pomysł który sugerujecie byłby lepszy, ale nie mogę tego ogarnąć logicznie, tzn. jak właśnie zrobić tą “zwyczajną edycję zwyczajnych modeli”.
Czy chodzi o stworzeni kopii produktu + jakiś znacznik że to element koszyka a nie zwykłej oferty, a w sesji użytkownika trzymać tylko id tych “nowych” produktów?

Kurcze, czasami mam wrażenie że brakuje mi jakiś podstaw, albo abstrakcyjnego myślenia :stuck_out_tongue:

To są te podstawy, których Ci brakuje: http://wazniak.mimuw.edu.pl/index.php?title=Bazy_danych
Słowo klucz: Projektowanie i normalizacja baz danych.

Może ktoś ma dla kolegi lepsze materiały?

Niestety, Olek, pozamiatałeś.
No chyba że kolega woli bardziej praktyczne wejście w temat, to wtedy w Agile Web Development With Rails jest przeczołganie właśnie przez tworzenie sklepu internetowego.

Mówię poważnie. AWDWR jest fajną książką (ja z nią zaczynałem) i bez problemu załapałem dzięki niej jak działa zwyczajna edycja zwyczajnych modeli. Tyle że wcześniej miałem świetny wykład z relacyjnych baz danych i wymagające laborki na których do bólu tłukliśmy diagramy ER.

Czasami pojawiają się ludzie (nie tylko na forum), którym takich podstaw brakuje i powoduje to dziwne problemy w stylu: tabela z 90 kolumnami (bo model może mieć wiele załączników) zamiast prostego has_many. Dlatego na poważnie pytam o jakiś sensowny artykuł pod tytułem: “Co to jest 3-cia postać normalna i jak z niej korzystać.”, bo to od tego trzeba zacząć.

[quote=tjeden]To są te podstawy, których Ci brakuje: http://wazniak.mimuw.edu.pl/index.php?title=Bazy_danych
Słowo klucz: Projektowanie i normalizacja baz danych.

Może ktoś ma dla kolegi lepsze materiały?[/quote]
Dzieki cala strona to skarbnica wiedzy dla studenta na technicznym kierunku

Terminy gonią, czas na naukę będzie niestety później.

Stworzyłem oto takiego potworka, którego nie mogę przeskoczyć.
Strona produktu.

[code]

<%= @product.name %>


<%= @product.description %>


Opcje wyceny

<%= form_for @product, :url => { :controller => “Cart”, :action => “add” } do |f| %>

<%= f.hidden_field :name %>
<% @product.options.each do |option| %>
<% f.fields_for :options do |b| %>

	<div>
	<%= option.name  %>
	<%= b.hidden_field :name %>
	
	<%= b.select :suboptionid, options_from_collection_for_select(option.suboptions, 'id', 'name') %>
	</div>

<% end %>
<% end %>

<div class="actions">
<%= f.submit 'dodaj do koszyka'%>
</div>

<% end %>

[/code] Uzyskać chce:

Nazwa produktu
opis

Opcje wyceny:
Format
Kolor

Teraz są dwie pętle, w efekcie przy trzech opcjach, każda zostaje wyświetlona trzy kornie w sumie 9.

Jest jakiś sposób by się pozbyć <% @product.options.each do |option| %>, i bym miał dostęp do tych danych w f.fields_for?

Np. zamiast <%= option.name %> <%= b.name %>, to samo przy przekazaniu kolekcji dla ?

Z reguły jestem pełen buddyjskiego współczucia, ale tym razem otwieram popcorn i z nieukrywaną szadenfrajdą będę obserwował jak podejście “nie mam czasu na naukę, muszę robić” gryzie kolejną osobę w dupala. :wink:

@Tomash, publika zawsze działa na mnie motywująco :slight_smile:

Powyższy problem rozwiązałem, kodu nie pokaże byście nie stracili tych mikroskopijnych resztek szacunku którego być może jeszcze do mnie macie :slight_smile:

Paperclip nadciągam!

Nie mamy, pokazuj :stuck_out_tongue:

Ja też chcę! :slight_smile:

[code]

<%= @product.name %>

<%= @product.description %>
Opcje wyceny

<%= form_for @product, :url => { :controller => “Cart”, :action => “add” } do |f| %>

<%= f.hidden_field :name %>

<% @product.options.each_with_index do |option, index| %>
	
	<%= option.name  %>
	<input id="product_options_attributes_<%= index %>_name" name="product[options_attributes][<%= index %>][name]" type="hidden" value="<%= option.name %>" />

	<select id="product_options_attributes_<%= index %>_suboptionid" name="product[options_attributes][<%= index %>][suboptionid]">
		<% option.suboptions.each do |o| %>
		<option value="<%= o.id %>"><%= o.name %></option>
		<% end %>
	</select>
	
<br />
<% end %>

<div class="actions">
<%= f.submit 'dodaj do koszyka'%>
</div>

<% end %>[/code]
W efekcie dostaje

session[:cart] {1=>{"name"=>"Towar1", "options_attributes"=>{"0"=>{"name"=>"Rozmiar", "suboptionid"=>"79"}, "1"=>{"name"=>"Wymiar", "suboptionid"=>"91"}, "2"=>{"name"=>"Kolor", "suboptionid"=>"95"}}}, 2=>{"name"=>"Towar2", "options_attributes"=>{"0"=>{"name"=>"Format", "suboptionid"=>"79"}, "1"=>{"name"=>"Typ", "suboptionid"=>"91"}}}}
Piękne co? :slight_smile:

No i mam nowe motto: Jeśli głupie rozwiązanie działa, to znaczy że nie jest głupie.

Za 3 dni nie będziesz wiedział o co chodzi w tym kodzie. Za 7 jeśli masz dobrą pamięć …

Jak używasz czegoś to poszukaj zawsze jakichś tutoriali, większość z tego co możesz zrobić w railsach jest już gdzieś opisana.

http://railscasts.com/episodes/196-nested-model-form-part-1

To co próbujesz zrobić możesz uzyskać zwykłym fields_for, nie ma potrzeby tworzyć własnych konstrukcji.

Ależ ja zrobiłem to według Rayana, wręcz identycznie, tylko nazwy się u mnie zmieniły survey=>product, question=>option, answer=>suboption. Tylko że to się tyczy utworzenia obiektu.

Problem u mnie jest z wyświetleniem tego po stronie użytkownika, jak wyświetlić wartość z pola option.name jako label dla pola select (lista subopcji) w fields_for?

select_tag “ala”, options_for_select(pole.collect { |x| [x.name, x.id] })

coś takiego jest, w sumie w dokumentacji sprawdź:

http://apidock.com/rails/ActionView/Helpers/FormOptionsHelper/options_for_select

i o samym select poczytaj i zobacz wszystko o formularzach Rayana jest tego kilka filmów

[quote=tjeden]To są te podstawy, których Ci brakuje: http://wazniak.mimuw.edu.pl/index.php?title=Bazy_danych
Słowo klucz: Projektowanie i normalizacja baz danych.

Może ktoś ma dla kolegi lepsze materiały?[/quote]
Skoro kolega taki zabiegany, to zawsze można mu jakiś kondensat zarzucić - niezbędne minimum: 1, 2, 3 i 4, które serwuje moim studentom :slight_smile: