Rails view unable to display form input parameters - ruby-on-rails

I'm trying to build a form that has an input for a question, and five inputs, each of which represents an answer choice.
My problem is that in my /show.html.erb file, it throws an error which I can't figure out.
For instance:
QUESTION
ANS1
ANS2
ANS3
ANS4
ANS5
Here's what I have so far:
# app/views/mcqs/new.html.erb
<%= form_for :mcq, url: mcqs_path do |f| %>
<%= f.label :title %><br>
<%= f.text_field :q %>
<%= f.label :ans1 %><br>
<%= f.text_field :ans1 %>
<%= f.label :ans2 %><br>
<%= f.text_field :ans2 %>
<%= f.label :ans3 %><br>
<%= f.text_field :ans3 %>
<%= f.label :ans4 %><br>
<%= f.text_field :ans4 %>
<%= f.label :ans5 %><br>
<%= f.text_field :ans5 %>
<%= f.label :category_id %><br>
<%= f.number_field :category_id %>
<%= f.label :tags %><br>
<%= collection_check_boxes(:mcq, :tag_ids, Tag.all, :id, :name) %>
<%= f.submit %>
<% end %>
The controller:
# app/controllers/mcqs_controller.rb
class McqsController < ApplicationController
def new
#Mcq = Mcq.new
end
def index
#questions = Mcq.all
end
def show
#Mcq = Mcq.find(params[:id])
end
def create
#Mcq = Mcq.new(params[:mcqs])
# #Mcq.save returns a boolean indicating whether the article was saved or not.
if #Mcq.save
redirect_to #Mcq
else
render 'new'
end
end
end
The view:
# app/news/mcqs/show.html.erb
<strong>MCQ Title:</strong><br>
<%= mcq.q %>
<strong>Question Text:</strong><Br>
<%= mcq.ans1 %>
...<strong>MCQ Title:</strong><br>
<%= mcq.q %>
<strong>Question Text:</strong><Br>
<%= mcq.ans1 %>
...
The error:
NameError in Mcqs#show
Showing app/views/mcqs/show.html.erb where line #4 raised:
undefined local variable or method `mcq' for #<#
<Class:0x007fad811936e8>:0x007fad838a47a0>
<strong>MCQ Title:</strong><br>
<%= mcq.q %>
</p><p>
How can I display the input of the new.html.erb on the show.html.erb without this error?. <%= #mcq.q %> doesn't work.

In your show method you create #Mcq as Mcq.find(params[:id]), but then in your show view you want to access to it as mcq, so you need to access it the same way (name) as you declared it within the controller.
Try with:
<strong>MCQ Title:</strong><br>
<%= #Mcq.q %>
If you create a #mcq on the controller (show method), and then you want to access to it in the view which responds to that method using #Mcq, then you will receive an object with NilClass, that's to say, if the names don't match, they won't work.
Also if you use #mcq on the controller, and then you want to access as mcq, that won't work neither, the one on your controller is an instance variable, available to be used within your views coming from your controllers, the second one is a local variable, and most probably it'll raise an undefined local variable or method 'variable' error.
I can quote to #Anhubaw with:
The main difference between local and instance variable is that local
variable is only available in controller, where as instance variable
is available in corresponding views also. The controller and views do
not share local variables

Change all #Mcq in controller to #mcp, and change all mcq in view to #mcq, also change :mcq in new view to #mcq.
The variable prefix with # means it is an instance variable, it can be accessible in the view, while the normal variable doesn't start with # is just a local variable, it just can be used in the controller action method.

Related

using an instance of appointment in the appointment model

I've created a form with some radio buttons and had to interpolate the appointment.id into the radio button and the label. However, Rails is throwing the error:
undefined method cancel_3 for Appointment.
So I have tried to make a method in the Appointment model to solve this by using define_method (see below). However as this is in the model, I'm unable to use the instance of appointment here.
Is there any way I can make this work?
define_method "cancel_#{appointment.id}" do
# ...
end
<%= f.radio_button "cancel_#{appointment.id}", :true %>
<%= f.label "cancel_#{appointment.id}_true", "Yes", class: "modal-options cancel" %>
<%= simple_form_for :appointment, url: delete_admin_appointment_path(appointment) do |f| %>
update your form with
<%= simple_form_for #appointment, url: delete_admin_appointment_path(#appointment) do |f| %>
and in your controller
def new
#apointment = Apointment.new
end
and radio button with
<%= f.radio_button "cancel_#{#appointment.id}", :true %>
<%= f.label "cancel_#{#appointment.id}_true", "Yes", class: "modal-options cancel" %>

In Ruby, how do I add multiple user input in f.number_field?

I'm a complete Ruby noob so please explain things to me like I'm 5. I have a form that has seven f.number_fields. I would like to add them and store them in :total. Here is an example of what I'm talking about:
<%= f.label :icecream %><br>
<%= f.number_field :icecream %>
<%= f.label :cake %><br>
<%= f.number_field :cake %>
So in this case I would like to take the user input from :icecream and :cake and add them and store it in :total, but how would I do that? This would then be stored in the database.
Ok you have your form in your view your model and your controller. What is going to happen is you are going to fill out your form that is in the new view for totals. Hit the submit button, that is going to make a request to your controller action create. In the create action it is going to make a call to the total_params method which is just going to check the params hash (which contains all the information that was just in you form in the view) to make sure it has values for the :total key and it will allow :cake and :icecream to be passed in (this is call strong parameters or white listing parameters), the private keyword is just so the total_params action is not directly accessed from outside the controller. Then in the create method the each look is going to iterate over the values in the hash returned by the call to total_params then add it to the variable total_value. One the each loop has finished a Total record will be created in they database with a total column value that is the sum of icecream and cake. This is approximately how you would go about storing a value.
View
#app/views/totals/new.html.erb
<%= form_for #total, url: {action: "create"} do |f| %>
<%= f.label :icecream %><br>
<%= f.number_field :icecream %>
<%= f.label :cake %><br>
<%= f.number_field :cake %>
<%= f.submit %>
Controller
#app/controllers/totals_controller.rb
class TotalsController << ApplicationController
def create
total_value = 0
total_params.each do |k, v|
total_value += v
end
Total.create(total: total_value)
end
private
def total_params
params.require(:total).permit(:cake, :icecream)
end
end
Model
#app/models/total.rb
class Total << ActiveRecord::Base
end

Rails, use a form field to set something on the user registration (devise)

I would really like to add a form field "invite_code" to the user sign up form, but I don't know how to add the invite_code to the controller so that the application knows how to look for it?
The form in the sign up on the template would read:
<% form_for User.new do |f| %>
<span>Email:</span> <% f.email %><br>
<span>Name:</span> <% f.name %><br>
<span>Invite Code:</span> <% f.invite_code %><br>
<% end %>
The "invite_code" isn't part of the database or anything, but in the user registration model, I want to put a:
before_save :invite_promo
def invite_promo
if #invite_code.present? && #invite_code == "special_person"
self.special_key = true
end
end
Is there an easy way to look for form fields in the template using the model or controller?
So sorry...I'm new to Rails. Thank you so much in advance!
You need to define a virtual attribute invite_code in User model:
attr_accessor :invite_code
Your form should look as follows:
<%= form_for User.new do |f| %>
<span>Email:</span> <%= f.email_field :email %><br>
<span>Name:</span> <%= f.text_field :name %><br>
<span>Invite Code:</span> <%= f.text_field :invite_code %><br>
<% end %>
if you don't want to create a field inside your table, you can use hidden field in view like, <%= hidden_field_tag :invite_code, 'code' %>

Does rails automatically pass '#variables' into partial?

I have a simple setup:
class EventsController < ApplicationController
def edit
#user = User.find(params[:user_id])
#event = Event.find(params[:id])
end
end
events\edit.html.erb:
<h1>Edit <%= #user.name %>'s event</h1>
<%= render 'form' %>
events\_form.html.erb:
<%= form_for [#user, #event] do |f| %>
<%= f.label :title %>
<%= f.text_field :title %>
<%= f.label :description %>
<%= f.text_area :description %>
<%= f.submit %>
<% end %>
To my biggest surprise this code is working and I am not getting any errors. Form partial knows about #user and #event!
I always thought I have to pass parameters as locals in order to access them in the partial, so the render from the view have to be:
<%= render 'form', user: #user, event: #event %>
And form_for line should be changed to:
<%= form_for [user, event] do |f| %>
Am I missing something here? Is it one of those days when I confused my self so much that I should probably get some sleep?
I am running this on Rails 4.1.4 and events are nested resources of user if that changes anything.
Your parameter is an instance variable. As such it is available to any partials rendered in the view.
You can check out more about rendering on the rails guides: http://guides.rubyonrails.org/getting_started.html#rendering-a-partial-form
It's good practice to pass in variables to partials as locals, as its easier to reuse the partial in other actions:
http://guides.rubyonrails.org/layouts_and_rendering.html#passing-local-variables
Also if you try to access a local variable you didn't pass into the partial, your view with explode, while an instance variable will just be nil. Having the view explode is, in my opinion, easier to debug.

How do I create default values in a Ruby Form?

This might be a really basic question but how do I create default values in forms?
I'm trying to put the <%= params[:id] %> of the page in as a default hidden value in this form.
`<% form_for(#revision) do |f| %>
<%= f.label :background_title %><br />
<%= f.text_field :background_title %><%= params[:id] %>
<%= f.label :title %><br />
<%= f.text_field :title %>
<%= f.submit 'Create' %>
<% end %>`
Thanks.
The form is linked to the object you pass to form_for, so set the value on the object before you start the form. For example, in the controller:
#revision.id = params[:id]
then in the form:
<%= f.hidden_field :id %>
However, I hope this is an example and you're not actually setting the ID (primary key) of an object based on a URL parameter...
If you are trying to create a new object, you can set the default values when you first instantiate a new object
def new
#revision = Revision.new(
:background_title => "Some Background Title",
:title => "Some Title"
)
end
then automatically the value of the fields will be set accordingly =) it's just that simple ;-)

Resources