Form_for - Ruby on Rails

Я не понимаю form_for.

Я пытаюсь реализовать этот учебник, и я не понимаю код вида.
Более того, я не понимаю api, иначе я бы не спросил здесь.

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

  • Что говорит :as => :user?
  • :url => sign_in_path понятен, но почему стоит (@user)?
  • И как я могу получить доступ к @user в другом View?
    3.1. Я также хочу войти в форму в application.html.erb (макет), НО @user находится в user_controller.rb, а не в application_controller.rb.
    Как я могу это сделать?
  • <%= form_for (User.new), ... работает хорошо, но я думаю, что это неправильно.
  • Почему есть что-то вроде for/forEach-loop? do |f| %>

Спасибо за вашу помощь!

Ответы

Ответ 1

Немного объяснения (form_for документация здесь):

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

Точка 1. :as => :user

Это имя, используемое для генерации имени ввода (и имен параметров), например:

= form_for Admin.new, as: :user do |f|
                          #^^^^
  = f.input :username

# will generate an input like this:
<input type='text' name='user[username]' #... />
                        #^^^^

Точка 2. :url => sign_in_path(@user)

В учебнике @user устанавливается следующим образом:

  def sign_in
    @user = User.new
  end

Точка 3. @user доступна в других действиях

Вы должны установить эту переменную в каждом действии, которое вы хотите. Он может быть избыточным, поэтому вы можете использовать файл before_filter для аутентификации, устанавливая переменную @user при каждом желаемом действии:

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

Если вы хотите сделать его доступным везде в своем приложении (подразумевается, что вы должны подключиться к учетной записи пользователя для просмотра приложения):

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

Точка 4. form_for (User.new)

Мы устанавливаем переменную @user в контроллер и передаем ее как аргумент form_for, потому что это Rails Convention никогда не вызывает имя модели непосредственно в представлениях, и она устарела, чтобы спровоцировать SQL-запросы в вид.

Пример:

######## WRONG
# view
<%= Post.find(params[:id]).title %>

######## MUCH BETTER
# controller action:
def show
  @post = Post.find(params[:id])

# view
<%= @post.title %>

Переменные экземпляра, заданные в действии контроллера , разделяются между действиями, его представлением и его частичными представлениями.


Точка 5. делать/завершать блок в form_for

Пожалуйста, дайте свой вклад в этот момент, не знаете, как это объяснить

Эта часть кода называется блоком do/end, представляет собой фрагмент кода, который будет выполняться в контексте form_for. Мы используем экземпляр form_for как переменную, определенную в трубах, здесь это |f|. Обычно я не использую |f|, это не очень важно для меня. Я предпочитаю использовать это имя переменной:

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

Что я считаю более понятным и понятным.