Мисля, че се бъркам в параметрите на Rails

Търся много в тези въпроси, но всъщност не виждам проблема си и се надявам да го направя...

( Свикнал съм да кодирам на C, C++ и т.н... но съм начинаещ в rails ... )

Имам изглед sign_up и когато изпратя, rails автоматично настройва всички полета на потребителя, които са попълнени във формуляра. Страхотно е, но сега искам да създам ново text_field и да взема въведеното от потребителя като текст в това text_field и да го използвам по-късно, без да задавам поле на друг потребител, казаха ми да използвам before_create и params или подобни неща, но след това аз m a noob ... В haml :

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, за да създадете "маркери за формуляри, които не разчитайте на обект на активен запис":

= 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