How can I access the newly built instance inside "fields_for"? - ruby-on-rails

I am creating a form for nested models by following this http://railscasts.com/episodes/196-nested-model-form-part-1.
The example in the link is that Survey model has 3 questions. Each Question has 4 answers. I copy the example here but remove the Answer model to make it simpler.
So the surveys_controller has a new method that looks like this.
# surveys_controller.rb
def new
#survey = Survey.new
3.times do
question = #survey.questions.build
end
end
in views/surveys/_form.html.erb, we have this:
<%= form_for #survey do |f| %>
<%= f.error_messages %>
<p>
<%= f.label :name %><br />
<%= f.text_field :name %>
</p>
<%= f.fields_for :questions do |builder| %>
<%= render "question_fields", :f => builder %>
<% end %>
<p><%= f.submit "Submit" %></p>
<% end %>
and finally this is views/surveys/_question_fields.html.erb
<p>
<%= f.label :content, "Question" %><br />
<%= f.text_area :content, :rows => 3 %><br />
<%= f.check_box :_destroy %>
<%= f.label :_destroy, "Remove Question" %>
</p>
My question is if I set an attribute of each question in the aforementioned new method, how can I show that value in views.
Let's say I modify the surveys_controller.rb to this:
# surveys_controller.rb
def new
#survey = Survey.new
3.times do
question = #survey.questions.build
question.another_attribute = another_value # added line
end
end
How to show the value of question.another_attribute inside <%= f.fields_for :questions do |builder| %> or _question_fields.html.erb?

You are passing :f => builder into the partial, so you can work with f. Calling f.object should return the form's object, in this case a question. So the following should work:
<%= f.object.another_attribute %>

Related

rails - Getting an id from the url and then passing it as an argument for creating an object

First off I would like to ask how to redirect after clicking the submit button in a creation form. I have a form for creating a quiz and after they hit submit I want to redirect them to the link 'quiz/:id/add_question' where :id is the id of the just created quiz, but instead I just get redirected to /quizzes and it leads to a "The connection was reset" error in my browser.
Here is my quiz form:
<div>
<h2>Create Quiz</h2>
<%= form_for(#quiz) do |f| %>
<div>
<%= f.label :name %>
<%= f.text_field :name %> </br>
<%= f.label :subject %>
<%= f.text_field :subject %>
</div>
<%= f.submit "Submit" %>
<% end %>
</div>
And my quizzes controller:
class QuizzesController < ApplicationController
def new
#quiz = Quiz.new
end
def create
#quiz = Quiz.new(quiz_params)
flash[:success] = "Quiz Created successfully" if #quiz.save
redirect_to 'quiz/' + #quiz.id.to_s + '/add_question'
end
private
def quiz_params
params.require(:quiz).permit(:name, :subject)
end
end
The quiz/:id/add_question link leads to a question creation form:
<div>
<%= form_for(#question) do |f| %>
<%= f.label :question %></br>
<%= f.text_field :question %></br>
<%= f.label :answer1 %></br>
<%= f.text_field :answer1 %></br>
<%= f.label :answer2 %></br>
<%= f.text_field :answer2 %></br>
<%= f.label :answer3 %></br>
<%= f.text_field :answer3 %></br>
<%= f.label :answer4 %></br>
<%= f.text_field :answer4 %></br>
<%= f.label :correct_id %></br>
<%= f.text_field :correct_id %></br>
<%= f.submit "Add question" %>
<% end %>
</div>
The other part of my question is how can I pass another argument for the creation of the question object here. I don't want the user to enter that argument because the argument should be the id from the current url (quiz/:id/add_question).
First of all i think you made a spelling error:
redirect_to 'quiz/' + #quiz.id.to_s + '/add_quesiton'
Should be
redirect_to 'quiz/' + #quiz.id.to_s + '/add_question'
But rather you should use the url helper that is available.
redirect_to quiz_add_question_path(#quiz.id)
Assuming thats the name of the route. You can find that name by running rake routes
For the id of the current quiz you can set a hidden attribute for example
<%= f.hidden_field :quiz_id, value: params[:id] %>

rails 4 - param is missing or the value is empty: projecttype

A newby to rails (I am building an app to learn rails) and run in to an issue I can't find a solution to (while following the getting started guide). I have studied the guides and similar questions
This is my code:
class ProjecttypesController < ApplicationController
def index
#projecttypes = Projecttype.all
end
def show
#projecttype = Projecttype.find(params[:id])
end
def new
end
def create
#projecttype = Projecttype.new(projecttype_params)
#projecttype.save
redirect_to #projecttype
end
private
def projecttype_params
params.require(:projecttype).permit(:name, :image, :url)
end
end
The form:
<%= form_for :projecttypes, url: projecttypes_path do |f| %>
<p>
<%= f.label 'Project type' %>
<%= f.text_field :projecttype %>
</p>
<p>
<%= f.label :name %>
<%= f.text_field :name %>
</p>
<p>
<%= f.label :image %>
<%= f.file_field :image %>
</p>
<p>
<%= f.label :url %>
<%= f.url_field :url %>
</p>
<p>
<%= f.submit %>
</p>
<% end %>
What am I doing wrong?
Perhaps important... when I use this...
def create
render plain: params[:projecttype].inspect
end
It returns 'nil'.
Thanks for your help
Your code should be like this
def new
#projecttype = Projecttype.new
end
def create
#projecttype = Projecttype.create(projecttype_params)
redirect_to #projecttype
end
and use this for form
<%= form_for #projecttype do |f| %>
In your
controller file
def new
#projecttype = Projecttype.new
end
and then in your form
<%= form_for #projecttype do |f| %>

Point a form to a specific controller action ruby on rails

Does anyone know how to point the following comments form to the hello action in my comments controller below, any advice would be appreciated:
<h2>Add a comment:</h2>
<%= form_for([#venue, #venue.comments.build]) do |f| %>
<p>
<%= f.label :commenter %><br />
<%= f.text_field :commenter %>
</p>
<p>
<%= f.label :body %><br />
<%= f.text_area :body %>
</p>
<p>
<%= f.submit %>
</p>
<% end %>
//////////////////my comments controller:
def hello
#venue = Venue.find(params[:venue_id])
#comment = #venue.comments.create(params[:comment].permit(:commenter, :body))
redirect_to venue_path(#venue)
end
You have to set route properly, for example:
resources :venues do
resources :comments do
collection do
post :hello
end
end
end
and set form url to this action's url:
<%= form_for(#venue.comments.build, url: hello_venue_comments_path(#venue)) do |f| %>

Form for related model not showing up

I am trying to have a form show up for a related model, but it is not displaying when I view the page in a browser. How do I url field in my fields_for to display?
Here is my code:
User Model:
class UsersController < ApplicationController
def new
#user = User.new
#user.websites.build
end
def create
#user = User.new(params[:user])
if #user.save
redirect_to root_url, :notice => "Signed up!"
else
render "new"
end
end
end
Website Model:
class Website < ActiveRecord::Base
belongs_to :user
end
Users View:
<h1>Sign Up</h1>
<%= form_for #user do |f| %>
<% if #user.errors.any? %>
...
<% end %>
<p>
<%= f.label :email %><br/>
<%= f.text_field :email %>
</p>
<p>
<%= f.label :password %><br/>
<%= f.password_field :password %>
</p>
<p>
<%= f.label :password_confirmation %><br/>
<%= f.password_field :password_confirmation %>
</p>
<% f.fields_for :websites do |builder| %>
<%= builder.label :url %><br/>
<%= builder.text_field :url %>
<% end %>
<p class="button"><%= f.submit %></p>
<% end %>
Final output:
You missed the equals sign in your erb tag.
<% f.fields_for :websites do |builder| %>
.. should be ..
<%= f.fields_for :websites do |builder| %>
Does that fix it?
It looks like you're maybe confusing singular and plural in your fields_for as well. Calling it with the plural websites then treating the block as a singular website doesn't make sense.

rails form data not getting saved to db

I'm new to rails and trying to make a simple site to start learning. When I submit my form, however, the data isn't saved to the db. I'm really not sure what's wrong, I've been trying to figure it out for a while. If I make a record in the rails console and save it, that one successfully shows up in the db (and on the index page).
calculate.rb:
class Calculate < ActiveRecord::Base
attr_accessible :number, :root
end
calculates_controller.rb:
class CalculatesController < ApplicationController
def index
#calculate = Calculate.all
end
def new
#calculate = Calculate.new
end
def create
#calculate = Calculate.new(params[:calculate])
if #calculate.save
redirect_to '/calculates'
else
render 'new'
flash[:notice] = "Didn't work"
end
end
end
new.html.erb:
<%= form_for(#calculate) do %>
<%= label_tag(:number, "Enter the number") %>
<%= text_field_tag :number %>
<%= label_tag(:root, "root") %>
<%= text_field_tag :root %>
<%= submit_tag("Submit") %>
<% end %>
if you are using form_for, use the form_for syntax
<%= form_for(#calculate) do |form| %>
<%= form.label :number %>
<%= form.text_field :number %>
<%= form.label :root %>
<%= form.text_field :root %>
<%= form.submit "Submit" %>
<% end %>
this will automatically handle the routes if the #calculate is new object it will submit it to create or if it is already saved it will send a put request to edit action
Ah hah! I updated my view to:
<%= form_for #calculate, :url => { :action => "create" } do |f| %>
<%= f.label :number %>
<%= f.text_field :number %>
<%= f.label :root %>
<%= f.text_field :root %>
<%= submit_tag("Submit") %>
<% end %>
And now it works. Awesome.

Resources