Validacja formularzy

Mam następny mały kłopot.

Chodzi o validację (nie generuje przez scaffold - wtedy dział)

ale jak generuję osobno kontroler i model

rails g controller Test2 index rails g model Test2 test:string
i nie działa:

mam błąd:

http://pstanek.megiteam.pl/test2s

a robie tak jak tu:

http://guides.rubyonrails.org/active_record_validations_callbacks.html

taki mam widok:

<%= form_for @test2 do |person_form| %> First name: <%= person_form.text_field :test %> <%= person_form.submit %> <% end %>
model:

class Test2 < ActiveRecord::Base validates_presence_of :test end
kontroler:

class Test2Controller < ApplicationController def index @test2 = Test2.new end end
Powinno zaznaczyć na czerwono…

PS jak zrobić taką validacje omijaąć ActiveRecord

ten helper jest dostępny w gemie “dynamic_form” (punkt 8 w podanym przez Ciebie linku). Najlepiej zrób scaffold i zobacz jak wygląda wyświetlanie błędów bez gema.

walidacje z ominięciem AR:
http://railscasts.com/episodes/219-active-model?view=asciicast

mam tego gem zainstalowanego dodałem do gemfile potem bundle install i zainstalował wszystko ładnie.
wygenerowałem przez scaffold kopiuje formularz z tego wygenerowanego do tego nie wygenerowanego i bład…

undefined method `error_messages’ for #ActionView::Helpers::FormBuilder:0xf64a0d5c

Udało się brakowało mi czegoś w kontrlerze itp… jest super. Wracam do nauki:)

Rou robie tak jak opisane w tym railcasts i mam taki error

undefined method `valids_path' for #<#<Class:0xf6af6f58>:0xf7318754>

klasa Messages zmieniłem sobie na Valid Reszto tak jak w tym opisie. kod w kod…

Wisz co to może być??

Co masz w routes.rb?

Hello::Application.routes.draw do root :to => 'home#index end

http://guides.rubyonrails.org/routing.html
Aby railsy wiedziały, którą akcję którego kontrolera wykonać, musisz niejako “spiąć” z tymi akcjami odpowiednie ścieżki. Do tego właśnie służy plik routes.rb.

“spiołem” mimo to mam nowy błąd

undefined method `key?' for nil:NilClass

model:

[code]class Valid
include ActiveModel::EachValidate
include ActiveModel::Validations
include ActiveModel::Conversion
extend ActiveModel::Naming

attr_accessor :name, :email, :content

validates_presence_of :name
validates_format_of :email, :with => /^[-a-z0-9_+\.]+\@([-a-z0-9]+\.)+[a-z0-9]{2,4}$/i
validates_length_of :content, :maximum => 500

def initialize(attributes = {})
  attributes.each do |name, value|
    send("#{name}=", value)
  end
end

def persisted?
  true
end

end[/code]
kontroler:

[code]class ValidController < ApplicationController

def new
@valid = ‘’
end

def create
@valid = Valid.new(params[:valid])
if @valid.valid?
# TODO send message here
flash[:notice] = “Message sent! Thank you for contacting us.”
redirect_to root_url
else
render :action => ‘new’
end
end
end[/code]
widok:

[code]<%= form_for @valid, :url => send_form_path do |f| %>

<%= f.error_messages %>

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

<%= f.label :email %>
<%= f.text_field :email %>

<%= f.label :content, "Message" %>
<%= f.text_area :content %>

<%= f.submit "Send Message" %>

<% end %>[/code] Routes

[code]Hello::Application.routes.draw do

match “/valid/index”, :to => “valid#new”, :valids_path => :new
match “send_form”, :to => “valid#create”, :patch => :create

root :to => ‘home#index’
end[/code]
PS http://railscasts.com/episodes/219-active-model?view=asciicast to nie działa bo jest na starej wersji rails pisane…

ma ktoś jakiś pomysł,

jeśli podajesz jakiś błąd to napisz której linii kodu on dotyczy a najlepiej kawałek logu z błędem

z loga

[code]…

Started GET “/send_form” for 91.227.39.58 at Wed Aug 29 15:14:22 +0200 2012

NoMethodError (undefined method key?' for nil:NilClass): actionpack (3.2.8) lib/action_controller/metal/hide_actions.rb:36:invisible_action?’
actionpack (3.2.8) lib/action_controller/metal/hide_actions.rb:18:in method_for_action' actionpack (3.2.8) lib/action_controller/metal/implicit_render.rb:14:inmethod_for_action’
actionpack (3.2.8) lib/action_controller/metal/compatibility.rb:61:in method_for_action' actionpack (3.2.8) lib/abstract_controller/base.rb:115:inprocess’
actionpack (3.2.8) lib/abstract_controller/rendering.rb:45:in process' actionpack (3.2.8) lib/action_controller/metal.rb:203:indispatch’
actionpack (3.2.8) lib/action_controller/metal/rack_delegation.rb:14:in dispatch' actionpack (3.2.8) lib/action_controller/metal.rb:246:inaction’
actionpack (3.2.8) lib/action_dispatch/routing/route_set.rb:73:in call' actionpack (3.2.8) lib/action_dispatch/routing/route_set.rb:73:indispatch’
actionpack (3.2.8) lib/action_dispatch/routing/route_set.rb:36:in call' journey (1.0.4) lib/journey/router.rb:68:incall’
journey (1.0.4) lib/journey/router.rb:56:in each' journey (1.0.4) lib/journey/router.rb:56:incall’
actionpack (3.2.8) lib/action_dispatch/routing/route_set.rb:600:in call' actionpack (3.2.8) lib/action_dispatch/middleware/best_standards_support.rb:17:incall’
rack (1.4.1) lib/rack/etag.rb:23:in call' rack (1.4.1) lib/rack/conditionalget.rb:25:incall’
actionpack (3.2.8) lib/action_dispatch/middleware/head.rb:14:in call' actionpack (3.2.8) lib/action_dispatch/middleware/params_parser.rb:21:incall’
actionpack (3.2.8) lib/action_dispatch/middleware/flash.rb:242:in call' rack (1.4.1) lib/rack/session/abstract/id.rb:205:incontext’
rack (1.4.1) lib/rack/session/abstract/id.rb:200:in call' actionpack (3.2.8) lib/action_dispatch/middleware/cookies.rb:339:incall’
activerecord (3.2.8) lib/active_record/query_cache.rb:64:in call' activerecord (3.2.8) lib/active_record/connection_adapters/abstract/connection_pool.rb:473:incall’
actionpack (3.2.8) lib/action_dispatch/middleware/callbacks.rb:28:in call' activesupport (3.2.8) lib/active_support/callbacks.rb:405:in_run__397314981__call__4__callbacks’
activesupport (3.2.8) lib/active_support/callbacks.rb:405:in send' activesupport (3.2.8) lib/active_support/callbacks.rb:405:in__run_callback’
activesupport (3.2.8) lib/active_support/callbacks.rb:385:in _run_call_callbacks' activesupport (3.2.8) lib/active_support/callbacks.rb:81:insend’
activesupport (3.2.8) lib/active_support/callbacks.rb:81:in run_callbacks' actionpack (3.2.8) lib/action_dispatch/middleware/callbacks.rb:27:incall’
actionpack (3.2.8) lib/action_dispatch/middleware/reloader.rb:65:in call' actionpack (3.2.8) lib/action_dispatch/middleware/remote_ip.rb:31:incall’
actionpack (3.2.8) lib/action_dispatch/middleware/debug_exceptions.rb:16:in call' actionpack (3.2.8) lib/action_dispatch/middleware/show_exceptions.rb:56:incall’
railties (3.2.8) lib/rails/rack/logger.rb:26:in call_app' railties (3.2.8) lib/rails/rack/logger.rb:16:incall’
actionpack (3.2.8) lib/action_dispatch/middleware/request_id.rb:22:in call' rack (1.4.1) lib/rack/methodoverride.rb:21:incall’
rack (1.4.1) lib/rack/runtime.rb:17:in call' activesupport (3.2.8) lib/active_support/cache/strategy/local_cache.rb:72:incall’
rack (1.4.1) lib/rack/lock.rb:15:in call' actionpack (3.2.8) lib/action_dispatch/middleware/static.rb:62:incall’
railties (3.2.8) lib/rails/engine.rb:479:in call' railties (3.2.8) lib/rails/application.rb:223:incall’
railties (3.2.8) lib/rails/railtie/configurable.rb:30:in send' railties (3.2.8) lib/rails/railtie/configurable.rb:30:inmethod_missing’
/usr/lib/ruby/gems/1.8/gems/thin-1.2.7/lib/thin/connection.rb:76:in pre_process' /usr/lib/ruby/gems/1.8/gems/thin-1.2.7/lib/thin/connection.rb:74:incatch’
/usr/lib/ruby/gems/1.8/gems/thin-1.2.7/lib/thin/connection.rb:74:in pre_process' /usr/lib/ruby/gems/1.8/gems/thin-1.2.7/lib/thin/connection.rb:57:inprocess’
/usr/lib/ruby/gems/1.8/gems/thin-1.2.7/lib/thin/connection.rb:42:in receive_data' /usr/lib/ruby/gems/1.8/gems/eventmachine-0.12.10/lib/eventmachine.rb:256:inrun_machine’
/usr/lib/ruby/gems/1.8/gems/eventmachine-0.12.10/lib/eventmachine.rb:256:in run' /usr/lib/ruby/gems/1.8/gems/thin-1.2.7/lib/thin/backends/base.rb:57:instart’
/usr/lib/ruby/gems/1.8/gems/thin-1.2.7/lib/thin/server.rb:156:in start' /usr/lib/ruby/gems/1.8/gems/thin-1.2.7/lib/thin/controllers/controller.rb:80:instart’
/usr/lib/ruby/gems/1.8/gems/thin-1.2.7/lib/thin/runner.rb:177:in send' /usr/lib/ruby/gems/1.8/gems/thin-1.2.7/lib/thin/runner.rb:177:inrun_command’
/usr/lib/ruby/gems/1.8/gems/thin-1.2.7/lib/thin/runner.rb:143:in run!' /usr/lib/ruby/gems/1.8/gems/thin-1.2.7/bin/thin:6 /var/lib/gems/1.8/bin/thin:19:inload’
/var/lib/gems/1.8/bin/thin:19

Rendered /home/pstanek/www/.ruby/gems/1.8/gems/actionpack-3.2.8/lib/action_dispatch/middleware/templates/rescues/_trace.erb (1.9ms)
Rendered /home/pstanek/www/.ruby/gems/1.8/gems/actionpack-3.2.8/lib/action_dispatch/middleware/templates/rescues/_request_and_response.erb (0.8ms)
Rendered /home/pstanek/www/.ruby/gems/1.8/gems/actionpack-3.2.8/lib/action_dispatch/middleware/templates/rescues/diagnostics.erb within rescues/layout (10.9ms)
… i duże tego …[/code]

No jak byk masz ze spodziewa się hash, a doajesz mu nil, czyli nic.

nie rozumiem. możesz jaśniej wiem ze daje nill ale gdzie to naprawić?

zmień persisted? na false.

to nic nie daje, już tak był. Dal testów dałem “true” ale i to nic nie dało…

na false jest

http://pstanek.megiteam.pl/messages jest ciut inny błąd

"uninitialized constant ActiveModel::EachValidate
"

nie ma czegoś takiego jak EachValidate

ok wywalilem i jest tak

http://pstanek.megiteam.pl/messages

jak masz czas mogę dać ci dostęp na ftp zerkniesz sobie (nie mam GIT)

Spójrz na to co masz w trace. Model, linijka nr 13. Nie ma takiej metody jak each dla obiektu nil. Co tam powinien być za obiekt? attributes, które dostajesz w parametrze. Jeżeli tego parametru nie prześlesz, to domyślnie będzie pusty hash, ale Ty tam przesyłasz parametr, tylko ten parametr ma wartość nil. Gdzie jest ten parametr przesyłany - w kontrolerze, linijka 7. Co tam przesyłasz - params[:valid], więc z widoku z formularza jak dostajesz params to nie ma w tym hashu takiego klucza jak :valid, dlatego jest nil.
Możesz albo w metodzie initialize wyjść z niej jak będzie nil, albo możesz w kontolerze nadpisać hash, np. params[:valid] ||= {} - ale to półśrodki, bo tak naprawdę masz błąd w formularzu i tam nie jest przesyłany odpowiedni parametr (albo podajesz jego złą nazwę w formularzu, sprawdź jakie paramsy otrzymujesz)

juz działa :slight_smile:

jak wywoływam ten URL to skrypt domagał się parametrów a ja ich nie przesyłałem… dzięk za pomoccc!

chodził o to http://pstanek.megiteam.pl/messages/new (jeszcze sobie testuje i oglądam)

Kontroler zmieniłem na takie coś:

[code]class MessagesController < ApplicationController

def create

if params[:messages]
  @messages = Messages.new(params[:messages])
else
  @messages = Messages.new
end

if @messages.valid?
  # TODO send message here
  flash[:notice] = "Message sent! Thank you for contacting us."
  @name = ''
  render :action => 'new'
  
else
  render :action => 'new'
end

end

end[/code]
Czy to dobre rozwiązanie?

Nie musisz robić pierwszego if’a. Nie ma sensu sprawdzenie czy przesyłasz parametry, bo jak będą puste (nil) to obiekt zostanie stworzony bez ich uwzględnienia więc wystarczy Ci “@messages = Messages.new(params[:messages])”.

Dalej, render możesz wywalić poza if’a odpuścić warunek “else” i całość zapisać w jednej lini. Pozatym coś mi się wydaje, żę flash Ci się nie pokaże, czegoś brakuje…

flash się pokazuje ładnie. chyba, że prócz pokazania ma się coś “dziać”?

Co do if też musi być bo dałem to wszystko do 1 metody…

Messages.new(params[:messages])

Jak wywale if to się pluje o parametry i mam błąd.undefined method `each' for nil:NilClass
Można też dać

def new @messages = Messages.new end

  • ma mała zmiana w routes.rb i też zadziała