Я думаю, что я возился с параметрами Rails

Я много ищу в этих вопросах, но на самом деле я не вижу своей проблемы, и я надеюсь, что...

(Я привык кодировать на C, C++ и т.д.... но я новичок в рельсах...)

У меня есть представление sign_up, и когда я отправляю, рельсы автоматически устанавливают все поля пользователя, которые заполняются в форме. Это круто, но теперь я хочу создать новое text_field и взять то, что пользователь вводит как текст в этом text_field, и использовать его позже, не устанавливая какое-либо поле другого пользователя, мне сказали использовать before_create и params или что-то в этом роде, но тогда я я нуб ... В хамле :

do |f|
  = f.text_field :email, :placeholder => "email"

работает хорошо (он устанавливает поле электронной почты с тем, что вводит пользователь)

do |f|
  = f.text_field NewVarThatIsNotAFieldOfCurrentNewUser, :placeholder => "referral code"

Затем происходит эта ошибка.

Error : undefined local variable or method `NewVarThatIsNotAFieldOfCurrentNewUser' (for the user class ofc)

Если вам нужна дополнительная информация/код, я отредактирую этот вопрос :)

Заранее спасибо !


person Charlon    schedule 12.09.2014    source источник


Ответы (3)


Ruby/Rails намного проще, чем C++

Вам не нужно "объявлять" новые переменные каждый раз, когда вы хотите их использовать - вы просто заполняете их для того, чтобы их позаботиться. Кроме того, Ruby/Rails объектно-ориентированный, что означает, что все, что вы делаете, должно быть основано на объектах.


Вар

Ваша ошибка указана так:

undefined local variable or method `NewVarThatIsNotAFieldOfCurrentNewUser'

Это означает, что вы пытаетесь загрузить переменную, которую еще не создали. Я упомянул, что вам не нужно объявлять переменные так же, как в C++, но вам нужно заполнить их данными или, по крайней мере, сделать их доступными для вашего приложения.

Чтобы сделать это, вам нужно объявить и заполнить переменную в вашем контроллере, хотя это подводит меня к следующему пункту — относительно контекста, в котором вы пытаетесь использовать переменную.

--

Объекты

Поскольку Rails/Ruby является объектно-ориентированным, это означает, что все, что вы делаете, должно быть сосредоточено вокруг объектов. Вот почему ваша ошибка указывает local variable or method -- у объектов есть «методы», а также данные

В любом случае, способ решить вашу проблему — убедиться, что атрибут, который есть у вашего пользователя, доступен, когда вы вызываете/создаете новый объект User. Для этого я бы рекомендовал использовать attr_accessor, хотя я не совсем уверен, что вы прошу быть честным.

Вот что я бы сделал:

#app/models/user.rb
class User < ActiveRecord::Base
   attr_accessor :new_attribute
end

#app/views/users/sign_up.html.erb
<%= form_for @user do |f| %>
   <%= f.text_field :new_attribute %>
   <%= f.submit %>
<% end %>

Это создаст то, что известно как virtual attribute, что означает, что он не будет сохранен в базе данных (поскольку база данных не поддерживает соответствующий атрибут)


Исправить

Если вы хотите собрать данные для «нового» атрибута, для которого у пользователя нет данных (который все еще находится в базе данных), вы, вероятно, захотите использовать следующее:

#app/views/users/sign_up.html.erb
<%= form_for @user do |f| %>
   <%= f.text_field :attribute %>
   <% end %>
<% end %>

Что касается того, о чем вы спрашиваете, я считаю, что метод attr_accessor является наиболее подходящим. Это даст вам возможность «повторно использовать» отправленные данные, не полагаясь на их сохранение в базе данных.

--

MVC

Наконец, чтобы дать вам больше контекста - я не знаю, насколько вы знакомы с MVC (полагаю, относительно), но я решил дать вам несколько идей о том, как работают приложения Rails:

введите здесь описание изображения

MVC означает, что у вас есть Model, view и Controller. Все это работает вместе, чтобы обеспечить базовый уровень функциональности для вашего приложения, предоставляя вам возможность создавать и редактировать данные из вашей БД.

Я упоминаю об этом потому, что если вы понимаете, как работает Rails с архитектурной точки зрения, вы будете в гораздо лучшем положении, чтобы использовать его. Например, вы упомянули, что вас смущает before_create, а затем отметили вопрос тегом before_action.

Эти два обратных вызова обслуживают разные части фреймворка Rails и, следовательно, не будут выполнять одну и ту же функциональность.

-- before_create для вашего Model

-- before_action для вашего Controller

person Richard Peck    schedule 12.09.2014

Вы можете использовать модуль FormTagHelper для создания тегов "form, которые не полагайтесь на объект Active Record":

= text_field_tag 'your_independent_field'

Это будет доступно как params[:your_independent_field] в вашем контроллере.

person Stefan    schedule 12.09.2014

Проверьте http://apidock.com/rails/ActionView/Helpers/FormTagHelper/text_field_tag метод. В рельсах, если вы создаете форму, например:

= form_for @some_obj do |f|

Затем каждое поле, созданное с помощью нотации f.something (например, f.text_field, f.submit), будет связано с объектом @some_obj. Поэтому, когда вы отправляете форму, все значения полей будут доступны из хэша params с помощью params[:some_obj] (например, params[:something][:email])

Вы можете использовать что-то вроде:

= form_for @some_obj do |f|
  = text_field_tag 'some_custom_param'
  = f.text_field :something

И после отправки хэш ваших параметров будет:

params[:some_obj][:something] # => will hold value of :something text field
params[:some_custom_param] # => will hold value of 'some_custom_param' text field ;) 
person Kuba Płoskonka    schedule 12.09.2014