Jak napisać helper dla formularza?

Zaczynam pisać helper do tworzenia formularza i od razu się zaciąłem. Poniżej kod z pliku application_helper.rb .
Najpierw miałem błąd: undefined method protect_against_forgery?' for #<ApplicationHelper::Form_with_tabs:0x77432ac> Dodałem include ActionController::RequestForgeryProtection. A teraz mam: undefined methodhelper_method’ for ApplicationHelper::Form_with_tabs:Class
mimo dodania jeszcze include ActionController::Helpers::ClassMethods

[code]# Methods added to this helper will be available to all templates in the application.

module ApplicationHelper

  class Form_with_tabs

    include ActionController::Helpers::ClassMethods
    include ActionController::RequestForgeryProtection
    include ActionView::Helpers::FormHelper
    include ActionView::Helpers::TagHelper
    include ActionView::Helpers::FormTagHelper
    include ActionView::Helpers::UrlHelper

    private
    def initialize( id, options = {} )
      @id = id
      @options = options
      @options.reverse_merge!({
        :disabled     => false
      })
    end

    public
    def create
      output = ''
      output << form_tag('/post')
      output << '</form>'
    end

  end

def form_with_tabs( id, options = {} )
  Form_with_tabs.new( id, options ).create
end

end[/code]
Wywołuję w widoku:

<%= form_with_tabs 'post' %>

Proszę o pomoc, albo wskazówkę czy w ogóle w dobrze się do tego zabieram.
To na razie tylko szkielet procedury ale jak nie działa to nie ma co dalej pisać.

Napisz co konkretnie ma robić ten Twój custom form with tabs, tzn (napisz jaki będzie output).

Pytam dlatego, że

  1. Albo już istnieje plugin który to robi lepiej
  2. Albo lepiej skorzystać z railsowego form buildera niż hackować to tak jak Ty powyżej.

Szukałeś w Google (np. custom form builder, tabular form builder) ? Zwraca sporo pluginów, ostatnio też widziałem fajny plugin do rozbudowanych formularzy gdzieś na githubie, mogę poszukać jeśli chcesz.

http://github.com/evilchelu/formtastic/tree/master
czyżby ten? :slight_smile:

Ten :slight_smile:

Czy w Railsach nie mogę napisać własnego helpera? Chciałbym po prostu to zrozumieć.
Napisać własnego helpera, którego zrozumiem i opanuję. Kilka już zresztą napisałem bez problemu.

Natomiast zaciąłem się na metodzie form_tag. A więc konkretnie chcę w moim helperze wywołać
metodę form_tag.

Miałem nadzieję, że ktoś lepiej zorientowany i doświadczony udzieli mi jakiejś wskazówki merytorycznej!
Gdyby wszyscy szukali tylko innych gotowych rozwiązań, to nic nowego by nie powstawało.

Na razie szukam w googlach. Jak coś znajdę to się podzielę.

Poszukaj więc kilku plug-inów na githubie, przeanalizuj ich kod źródłowy, i wtedy napisz coś własnego. Jest to absolutnie ok. Trudno natomiast wymagać od innych na forum, żeby prowadzili Ciebie za rękę, kiedy istnieją dobre, sprawdzone rozwiązania.

Najlepiej spójrz na kod powyższego plugina i jeżeli rzeczywiście bardzo Ci potrzebna klasa, a zwykłe metody nie wystarczą, to obczaj konstrukcję.

Hint: opcja :builder dla form

I udało się zrobić to co planowałem. Poniżej szkielet mojego rozwiązania.
Mnie się przyda. A może ktoś też skorzysta.

[code]# Methods added to this helper will be available to all templates in the application.

module ApplicationHelper

class Active_Form_with_tabs

private
def initialize( id, object, template, options = {} )
  @id = id
  @object = object
  @template = template
  @object = (@template.instance_variable_get("@#{@object}") rescue @object) # object można podać jako @name lub 'name'
  @options = options
end

public
def create
  output = ''
  @template.fields_for @object do |f|
    @object.class.columns.each do |fld|
                         # zamiast fld.name - można podać cokolwiek np. f.text_field ...
      output << fld.name # ... I tu już mogę robić co potrzebuję z polami formularza 
                         # (wybierać pola, zmieniać kolejność, grupować w sety lub taby)
    end
    output << f.submit
  end
end

end

def form_with_tabs( id, object, options = {} )
output = form_tag options, {:id=>id}
output << Active_Form_with_tabs.new( id, object, self, options ).create
output << ‘’
end

end[/code]
Dzięki za inspiracje.

Jako purysta językowy chciałbym Ci tylko zwrócić uwagę na nazwę klasy:

class Active_Form_with_tabs end
Nie lepiej tak?

class ActiveFormWithTags end
Rozumiem, że to tak zwany styl PHP czyli “jak popadnie” ;). Konwencją Rubiego dla nazw klas jest CamelCase, ale nawet jak się upierasz przy Camel_Case to bądź konsekwentny.

private def initialize( id, object, template, options = {} )
Ruby sam zadba o to by metoda initialize była prywatna.

A tak poza tym gratuluję cierpliwości :).