virtual model and form_for (or formtastic)

2020-05-21 06:18发布

问题:

Sometimes we need form without model creation - for example search field or email, where should be send some instructions. What is the best way to create this forms? Can i create virtual model or something like this? I'd like to use formtastic, but not form_tag.

回答1:

Firstly, Formtastic doesn't need a model in all cases, although it certainly works best and requires less code with a model.

Just like Rails' own built-in form_for, you can pass in a symbol instead of an object as the first argument, and Formtastic will build the form and post the params based on the symbol. Eg:

<% semantic_form_for(:session) do |f| %>
  ...
<% end %>

This will make the form values available to your controller as params[:session].

Secondly, a model doesn't mean an ActiveRecord model. What I mean is, Formtastic will work with any instance of a class that quacks like an ActiveRecord model.

A classic example of this that many people are using Authlogic for authentication with Formtastic. Part of Authlogic is the idea of a UserSession model, which works fine:

Controller:

def index
  @user_session = UserSession.new
end

Form:

<% semantic_form_for(@user_session) do |f| %>
  <%= f.input :login %>
  <%= f.input :password %>
<% end %>

This will make your form data available in your controller as params[:user_session].

It's really not that hard to create a model instance to wrap up the concerns of your model. Just keep implementing the methods Formtastic is expecting until you get it working!



回答2:

default_language.rb

class DefaultLanguage
  attr_accessor :language_id
end

foo_controller.rb

  def index
    @default_language = params[:default_language] || Language.find_by_name("English")
  end

index.erb

<% semantic_form_for @default_language do |form| %>
  <% form.inputs :id => 'default_language' do %>
      <%= form.input :id, 
       :as => :select, 
       :collection => @languages, 
       :required => false, 
       :label => "Primary Language:", 
       :include_blank => false %>
    <% end %>
  <% end %>

I used AJAX to post the form when the value changed.



回答3:

Or you simply create a form with form_for and leave the model reference blank. for example <% form_for "", :url=>some_url do |f| %> <%= f.text_field "some_attribute" %> <%= submit_tag "submit" %>

You can fetch the values by simply saying params[:some_attribute] in your controller.