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 trial

Ruby

Naomi Freeman
STAFF
Naomi Freeman
Treehouse Guest Teacher

Radio 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
Nick Fuller
9,027 Points

Hi 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
Naomi Freeman
Treehouse Guest Teacher

Thanks :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?

Naomi Freeman
STAFF
Naomi Freeman
Treehouse Guest Teacher

You 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
Nick Fuller
9,027 Points

Excellent! Good job trouble shooting, sorry for the curve ball :P