Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

form_for - Ruby on Rails

Tags:

I do not understand the form_for.

I try to implement this tutorial and I do not understand the view-code.
Moreover I dont understand the api, otherwise I wouldnt asked here..

<%= form_for @user, :as => :user, :url => sign_in_path(@user) do |f| %>

  1. What does the :as => :user say ?
  2. :url => sign_in_path is clear, but why is there a (@user) behind it?
  3. And how can I get access to @user in a different View?
    3.1. I also want the log-in-form in the application.html.erb (the layout), BUT the @user is in the user_controller.rb and not in the application_controller.rb.
    How can I do this?
  4. <%= form_for (User.new), ... works well, but I think it isn't right..
  5. Why is there something like a for/forEach-loop? do |f| %>

Thanks for your help!

like image 919
Ismoh Avatar asked Apr 08 '14 15:04

Ismoh


People also ask

What is Form_for in Ruby?

The form_for method automatically includes the model id as a hidden field in the form. This is used to maintain the correlation between the form data and its associated model. Some ORM systems do not use IDs on nested models so in this case you want to be able to disable the hidden id.

What is a form helper in Rails?

1.3 Helpers for Generating Form Elements Rails provides a series of helpers for generating form elements such as checkboxes, text fields, and radio buttons. These basic helpers, with names ending in _tag (such as text_field_tag and check_box_tag ), generate just a single <input> element.


1 Answers

A little explanation ( form_for documentation here):

<%= form_for @user, :as => :user, :url => sign_in_path(@user) do |f| %> 

Point 1. :as => :user

This is the name used to generate the input's name (and the params' names), example:

= form_for Admin.new, as: :user do |f|                           #^^^^   = f.input :username  # will generate an input like this: <input type='text' name='user[username]' #... />                         #^^^^ 

Point 2. :url => sign_in_path(@user)

In the tutorial, @user is set like this:

  def sign_in     @user = User.new   end 

Point 3. @user available in other actions

You have to set this variable in each action you want it. It can be redundant, so you can use a before_filter in order to authenticate set the @user variable at each action your want:

class UsersController < ApplicationController   before_filter :set_user_variable    def set_user_variable     @user ||= User.find(session[:user_id]) if session[:user_id].present?   end end 

If you want to make it available everywhere in your app (implies that you must be connected to a user account to browse the app):

class ApplicationController < ActionController::Base   before_filter :set_user_variable, except: [:sign_in, :login]    def set_user_variable     @user ||= User.find(session[:user_id]) if session[:user_id].present?   end 

Point 4. form_for (User.new)

We set the variable @user in the controller and pass it as an argument to form_for because it is a Rails Convention to never call a Model's name directly in the views, and it is deprecated to provoke SQL queries in the view.

Example:

######## WRONG # view <%= Post.find(params[:id]).title %>  ######## MUCH BETTER # controller's action: def show   @post = Post.find(params[:id])  # view <%= @post.title %> 

Instance Variables set in the Action of a Controller are shared between the actions, its view and its partial views.


Point 5. do/end block in form_for

Please give your input at this point, not sure how to explain it

This part of the code is called a do/end block, it represents a piece of code that will be executed in the context of the form_for. We use the form_for's instance as the variable defined in the pipes, here it is |f|. I usually don't use |f|, it is not really relevant to me. I prefer to use this kind of variable name:

= form_for @user do |user_form_builder|   = user_form_builder.input :username 

Which I think is more readable and easier to understand.

like image 118
MrYoshiji Avatar answered Sep 29 '22 07:09

MrYoshiji