ROR - metody i klasy

Mam pewien kłopot z frameworkiem ROR 3.2.6 (Ruby 1.9.3-p194)

Robię przykład/tutorial z: “Ruby on Rails Tutorial Part 6 - CRUD - Create - Save Method” na Youtube.pl

Dla: “<%= form_for @post do |local| %><% end %>” a konkretnie dla “form_for”,
zlokalizowanego w Showing /var/www/blog/app/views/post/new.html.erb where line #2

Mam błąd: NoMethodError in Post#new
Showing /var/www/blog/app/views/post/new.html.erb where line #2 raised:
undefined method `posts_path’ for #<#Class:0xb54761c4:0x93eda9c>

Wydaje mi się, że zrobiłem wszystko dobrze i uważnie, jak tutorial wskazuje. Jak dotrzeć do metod i klasy z której korzysta “form_for” i skąd te dziwne błędy, ?

Pokaż config/routes.rb.

Bo pisanie form_for OBIEKT bez podawania ścieżki uruchamia REST-ową magiczną machinę Railsów. To nie jest fajne dla początkującego, ale wszyscy się uparli tak pisać tutoriale.

pokaż co masz w routes.rb związanego z posts, może tam siedzi błąd :slight_smile:

“uruchamia REST-ową magiczną machinę Railsów”
nawykłem z innych języków że lubię wiedzieć co się dzieje za kurtyną :stuck_out_tongue:

routes.rb:

Blog::Application.routes.draw do
resources :post

#komentarze

end

Wybaczcie mi za nadgorliwość, ale wkleję jeszcze to:

controllers/post_controller.rb:

class PostController < ApplicationController
def index
@post_for_index = Post.all
end
def show
@post_for_show = Post.find(params[:id])
end
def new
@post = Post.new
end
def edit

end
end

views/post/index.html.erb:

MY BLOG

<% @post_for_index.each do |local| %>

<%= link_to local.nick, local %>

<%= local.posttitle %>

<%= local.postcontent %>


<% end %>

<%= link_to "Dodaj post", new_post_path %>

views/post/new.html.erb:

Dodaj post

<%= form_for @post do |local| %>
<p><%= local.label :nick %></p><br />
<p><%= local.text_filed :nick %></p><br />

<p><%= local.label :posttitle %></p><br />
<p><%= local.text_filed :posttitle %></p><br />

<p><%= local.label :postcontent %></p><br />
<p><%= local.text_area :postcontent %></p><br />

<p><%= local.submit "Dodaj post" %></p><br />

<% end %>

db/migrate/20120703173327_create_posts.rb:

class CreatePosts < ActiveRecord::Migration
def change
create_table :posts do |t|
t.string :nick
t.string :posttitle
t.text :postcontent

  t.timestamps
end

end
end

Używaj liczby mnogiej dla kontrolerów: PostsController, resources :posts

hmmm. Nie wiem dlaczego próbuje odwołać się do posts_path zamiast post_path. Wszystkie zmienne/obiekty/pliki jakie stworzyłem - nazwałem w liczbie pojedynczej.

form_for @posts standardowo użyje posts_path, jeżeli chcesz użyć innej ścieżki to podaj ją jako parametr :url => ‘moj_path’

Jednak w tej sytuacji sugerowałbym zastosowanie konwencji i nazwanie modeli i ścieżek jak Bóg przykazał :slight_smile:

a przy okazji - @post_for_index, @post_for_show? wtf?

po prostu: @posts (dla #index) i @post (dla #show) :slight_smile:

Bardzo dziękuję za odpowiedź, pomogło. :slight_smile: :slight_smile:

Nie miałem pojęcia, że ROR narzuca mi konwencję nazewnictwa plików i obiektów, tzn. że to ma się nazywać tak a nie inaczej, trochę to dziwne dla mnie. Dlaczego ROR narzuca mi konwencję: to ma się nazywać post, a tamto posts? Skąd ROR może wiedzieć co chcę stworzyć, a jeśli chcę nazwać po polsku wiadomosc i wiadomosci?

Nie rozumiem.

Railsy niczego nie narzucają. Jak się uprzesz to możesz sobie wszystko nazywać jak Ci się podoba.

http://en.wikipedia.org/wiki/Convention_over_configuration.

Railsy działają według pewnych konwencji - jeżeli twój model nazywa się Post, to twój kontroler - PostsController, twoje widoki będą w views/posts a url do kontrolera to /posts/ itd. itd. Same z siebie wtedy wiedzą gdzie czego szukać.

No i nie chodzi tylko o framework. Kiedy nowy programista wchodzi do projektu też wie gdzie, co i jak bo wszystkie railsowe appki wyglądają mniej więcej tak samo.

Nie jest to żaden przymus, tylko pewna… wskazówka - “rób tak, a będzie ci łatwiej i większość rzeczy będzie działać ootb” :wink:

You create/modify/destroy a POST.

POSTS’ CONTROLLER manages your actions.

Mniej więcej według tego to działa.

To wtedy ładujesz się w niezłe bagno.

Dokładnie, kod po Polsku to tylko na uczelni można spotkać. Żaden szanujący się programista rails tego nie robi.

Od tego masz w railsach locale, zeby kod był po angielsku a uzytkownik widział wszystko np. po polsku

Da się to oczywiście zrobić, spójrz w config/initializers/inflector.rb

Ale tak jak sharnik napisał: nie warto.

Dziękuję za waszą pomoc.

Chociaż jest coś dla mnie dziwnego w tym:

mam plik index.html.erb w posts/views
<% @posts.each do |_post| %>

<%= link_to _post.nick, _post %>


<%= _post.posttitle %>


<%= _post.postcontent %>



<%= link_to “Edytuj”, edit_post_path(_post) %>
<%= link_to “Usuń”, _post, :method => :delete %>




<% end %>

Dziwne to dla mnie i do końca niezrozumiałe - skąd te różnice, tu :method => :delete, tu _post, a tu edit_post_path(_post)?

Mogło by być bardziej ujednolicone:
<%= link_to _post.nick, _post, :method => :show %>
<%= link_to " Edytuj", _post, :method => :edit %>
<%= link_to “Usuń”, _post, :method => :delete %>

Dlaczego właściwie “_post”, a nie po prostu “post”?
Zauważ, że w metodzie link_to drugi argument odpowiedzialny jest za ścieżkę - jak widzisz - w obu przypadkach (show i destroy) drugi argument jest jest taki sam, co jest w tym zatem dziwnego?
A do edit jest inaczej - bo i “domyślna”(restful) ścieżka do edytowania zasobu jest inna niż do jego pokazywania, czy usuwania - co w sumie nie powinno dziwić.

Poprawiłem post powyższy, żeby być lepiej zrozumianym, więc jeśli chodzi o show i destroy akcja jest ta sama, w url przekazywane jest id.
Dlaczego więc: w jednym przypadku :method => :delete, a w drugim _post ?

Jak to w PHP, lokalne zmnienne pisało się dodając _

Nie, akcja nie jest ta sama. Przy pokazywaniu wywoływana jest akcja show, przy usuwaniu - delete. Natomiast to, co przekazujesz jako :method, jest zupełnie czym innym - to jest metoda protokołu http. I tak - domyślnie link_to tworzy link z metodą get - jak odpalisz sobie rake routes, to zobaczysz, że właśnie get /posts/:id prowadzi do Posts#show. Natomiast delete /posts/:id prowadzi do akcji delete - dlatego też przy linku do usuwania musisz jawnie określić, że link powinien posłużyć się metodą delete.
Poza tym, przecież w obydwu przekazujesz “_post”. :wink:

http://api.rubyonrails.org/classes/ActionView/Helpers/UrlHelper.html#method-i-link_to przeczytaj sobie :wink: może coś się rozjaśni :slight_smile:

ino Ruby to nie PHP :wink: