Welcome to the Treehouse Community
Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.
Looking to learn something new?
Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.
Start your free trialNaomi Freeman
Treehouse Guest TeacherRadio buttons + controller
Hi there,
I am trying to create a radio button that has 2 buttons.
In the controller, I want it to redirect one place if option 1 and redirect somewhere else if option 2.
I am finding lots on the internet about how to set up the html, but not how to set up my controller.
Can you please help? The redirect is working on save, but it default goes to private area no matter which option I choose. It is going though.
<%= form_for(@profile) do |f| %>
<% if @profile.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(@profile.errors.count, "error") %> prohibited this profile from being saved:</h2>
<ul>
<% @profile.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :first_name %><br>
<%= f.text_field :first_name %><br>
<%= f.label :last_name %><br>
<%= f.text_field :last_name %><br>
<%= f.label :building %><br>
<%= f.text_field :building %><br>
<%= f.label :unit %><br>
<%= f.text_field :unit %><br>
<p> Please choose one of the following options: </p>
<div id="radio_buttons">
<%= radio_button_tag(:location_option, 'unit', :value => 'unit') %>
<%= label_tag(:location_private, "A repair is needed in my unit.") %>
<%= radio_button_tag(:location_option, 'common', :value => 'common') %>
<%= label_tag(:location_common, "A repair is needed in a common area of the building.") %>
</div>
</div>
<div class="actions">
<%= f.submit %>
<%#= link_to :remote => true, 'Submit now', :url => {:action=>"create"}, :submit =>
'radio_buttons' %>
</div>
<% end %>
class ProfilesController < ApplicationController
before_action :set_profile, only: [:show, :edit, :update, :destroy]
# GET /profiles
# GET /profiles.json
def index
@profiles = Profile.all
end
# GET /profiles/1
# GET /profiles/1.json
def show
end
# GET /profiles/new
def new
@profile = Profile.new
end
# GET /profiles/1/edit
def edit
end
# POST /profiles
# POST /profiles.json
def create
@profile = Profile.new(profile_params)
respond_to do |format|
if @profile.save && @location_option == @unit
format.html { redirect_to new_private_area_path(@profiles), notice: 'Profile was successfully created.' }
format.json { render action: 'show', status: :created, location: @profile }
elsif @profile.save && @location_option == @common
format.html { redirect_to new_common_area_path(@profiles), notice: 'Profile was successfully created.' }
format.json { render action: 'show', status: :created, location: @profile }
else
format.html { render action: 'new' }
format.json { render json: @profile.errors, status: :unprocessable_entity }
end
end
end
# def create
# @profile = Profile.new(profile_params)
# respond_to do |format|
# if @profile.save && @value == 'private' #remember that params come back as strings
# format.html { redirect_to new_private_area_path(@profiles), notice: 'Profile was successfully created.' }
# format.json { render action: 'show', status: :created, location: @profile }
# elsif @profile.save && @value == 'common'
# format.html { redirect_to new_common_area_path(@profiles), notice: 'Profile was successfully created.' }
# format.json { render action: 'show', status: :created, location: @profile }
# else
# format.html { render action: 'new' }
# format.json { render json: @profile.errors, status: :unprocessable_entity }
# end
# end
# end
# PATCH/PUT /profiles/1
# PATCH/PUT /profiles/1.json
def update
respond_to do |format|
if @profile.update(profile_params)
format.html { redirect_to @profile, notice: 'Profile was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: 'edit' }
format.json { render json: @profile.errors, status: :unprocessable_entity }
end
end
end
# DELETE /profiles/1
# DELETE /profiles/1.json
def destroy
@profile.destroy
respond_to do |format|
format.html { redirect_to profiles_url }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_profile
@profile = Profile.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def profile_params
params.require(:profile).permit(:first_name, :last_name, :building, :unit, :location_option)
end
end
3 Answers
Nick Fuller
9,027 PointsHi Summer!
I see what you're trying to accomplish and you're logic looks good, but you're missing a little something.
In the create action your logic states:
if @profile.save && @location_option == @unit
format.html { redirect_to new_private_area_path(@profiles), notice: 'Profile was successfully created.' }
format.json { render action: 'show', status: :created, location: @profile }
elsif @profile.save && @location_option == @common
format.html { redirect_to new_common_area_path(@profiles), notice: 'Profile was successfully created.' }
format.json { render action: 'show', status: :created, location: @profile }
else
format.html { render action: 'new' }
format.json { render json: @profile.errors, status: :unprocessable_entity }
end
The issue is you're not setting the variables @location_option
and @unit
anywhere in that method. So what happens is when a variable is not set in ruby it defaults to nil (which is an object!). So what is happening in this method is ruby will first check if the @profile.save returns true (which is does) then it is checking if @location_option (which is nil) == @unit (which is also nil) which will always be true. So that is why you keep getting into the new_private_area_path
.
To verify this, open irb and simply type @location_option == @unit
and since neither of those variables are set it will return true
.
So long story short, you need to set the value of @location_option
and have it check the appropriate params returned by your form.
maybe
def create
@profile = Profile.new(profile_params)
@location_option = params[:profile][:location_option]
respond_to do |format|
if @profile.save && @location_option == 'unit'
format.html { redirect_to new_private_area_path(@profiles), notice: 'Profile was successfully created.' }
format.json { render action: 'show', status: :created, location: @profile }
elsif @profile.save && @location_option == 'common'
format.html { redirect_to new_common_area_path(@profiles), notice: 'Profile was successfully created.' }
format.json { render action: 'show', status: :created, location: @profile }
else
format.html { render action: 'new' }
format.json { render json: @profile.errors, status: :unprocessable_entity }
end
end
end
Naomi Freeman
Treehouse Guest TeacherYou were (mostly) right :) It's just that how @location_option is set up here nests it, whereas mine isn't actually nested.
Got it all straightened out though. Thanks!
Nick Fuller
9,027 PointsExcellent! Good job trouble shooting, sorry for the curve ball :P
Naomi Freeman
Treehouse Guest TeacherNaomi Freeman
Treehouse Guest TeacherThanks :D I will play with that, see if I can make it go.
Nope. Now it's doing the failed option instead, redirecting to the edit option. So it's doing something differently. Guess that's a start. Anyone have any further thoughts on what I'm missing?