Devon Kiss
Devon Kiss

Reputation: 239

Passing form input values from query string results in blank attributes

I am trying to pass data from one application to another by using a query string with a link:

domain-example.com/authorizations/new?name=Some%20Name&[email protected]&type_of_booking=DEP&booking_id=101&price=1001

I am successfully getting the values from the query string into the form inputs but when the form is submitted the values are blank in the database.

The controller has whitelisted the attributes as well.

Here is my code. What could be going on here?

_form.html.erb

<%= form_with(model: authorization, local: true) do |form| %>
  <div class="field">
    <%= form.hidden_field :name, value: params[:name] %>
  </div>

  <div class="field">
    <%= form.hidden_field :email, value: params[:email] %>
  </div>

  <div class="field">
    <%= form.hidden_field :type_of_booking, value: params[:type_of_booking] %>
  </div>

  <div class="field">
    <%= form.hidden_field :booking_id, value: params[:booking_id] %>
  </div>

  <div class="field">
    <%= form.hidden_field :price, value: params[:price] %>
  </div>

  <div class="actions">
    <%= form.submit %>
  </div>
<% end %>

authorizations_controller.rb

class AuthorizationsController < ApplicationController
  before_action :set_authorization, only: [:show, :edit, :update, :destroy]

  # GET /authorizations
  # GET /authorizations.json
  def index
    @authorizations = Authorization.all
  end

  # GET /authorizations/1
  # GET /authorizations/1.json
  def show
  end

  # GET /authorizations/new
  def new
    @authorization = Authorization.new
  end

  # GET /authorizations/1/edit
  def edit
  end

  # POST /authorizations
  # POST /authorizations.json
  def create
    @authorization = Authorization.new(authorization_params)

    respond_to do |format|
      if @authorization.save
        format.html { redirect_to @authorization, notice: 'Authorization was successfully created.' }
        format.json { render :show, status: :created, location: @authorization }
      else
        format.html { render :new }
        format.json { render json: @authorization.errors, status: :unprocessable_entity }
      end
    end
  end

  # PATCH/PUT /authorizations/1
  # PATCH/PUT /authorizations/1.json
  def update
    respond_to do |format|
      if @authorization.update(authorization_params)
        format.html { redirect_to @authorization, notice: 'Authorization was successfully updated.' }
        format.json { render :show, status: :ok, location: @authorization }
      else
        format.html { render :edit }
        format.json { render json: @authorization.errors, status: :unprocessable_entity }
      end
    end
  end

  # DELETE /authorizations/1
  # DELETE /authorizations/1.json
  def destroy
    @authorization.destroy
    respond_to do |format|
      format.html { redirect_to authorizations_url, notice: 'Authorization was successfully destroyed.' }
      format.json { head :no_content }
    end
  end

  private
    # Use callbacks to share common setup or constraints between actions.
    def set_authorization
      @authorization = Authorization.find(params[:id])
    end

    # Never trust parameters from the scary internet, only allow the white list through.
    def authorization_params
      params.require(:authorization).permit(:name, :email, :type_of_booking, :booking_id, :price)
    end
end

Console log of entire transaction:

Started GET "/authorizations/new?name=Example%20Name&[email protected]&type_of_booking=DEPRT&booking_id=101&price=1001" for ::1 at 2019-04-15 11:26:19 -0500
Processing by AuthorizationsController#new as HTML
  Parameters: {"name"=>"Example Name", "email"=>"[email protected]", "type_of_booking"=>"DEPRT", "booking_id"=>"101", "price"=>"1001"}
  Rendering authorizations/new.html.erb within layouts/application
  Rendered authorizations/_form.html.erb (6.9ms)
  Rendered authorizations/new.html.erb within layouts/application (25.5ms)
Completed 200 OK in 128ms (Views: 120.8ms | ActiveRecord: 0.0ms)


Started POST "/authorizations" for ::1 at 2019-04-15 11:26:40 -0500
Processing by AuthorizationsController#create as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"q2vaB4Eq49J8LFFeHtbWfR7EYlfZPA6ouFoEEfLXtnduo2i7i1J/dH9JajVobPIWm5N4VHF5JuwY0Mn8nC2K2A==", "authorization"=>{"name"=>"Example Name", "email"=>"[email protected]", "type_of_booking"=>"DEPRT", "booking_id"=>"101", "price"=>"1001"}, "commit"=>"Create Authorization"}
   (0.3ms)  BEGIN
  ↳ app/controllers/authorizations_controller.rb:30
  Authorization Create (2.2ms)  INSERT INTO "authorizations" ("created_at", "updated_at") VALUES ($1, $2) RETURNING "id"  [["created_at", "2019-04-15 16:26:40.061749"], ["updated_at", "2019-04-15 16:26:40.061749"]]
  ↳ app/controllers/authorizations_controller.rb:30
   (42.5ms)  COMMIT
  ↳ app/controllers/authorizations_controller.rb:30
Redirected to http://localhost:3000/authorizations/4
Completed 302 Found in 58ms (ActiveRecord: 44.9ms)


Started GET "/authorizations/4" for ::1 at 2019-04-15 11:26:40 -0500
Processing by AuthorizationsController#show as HTML
  Parameters: {"id"=>"4"}
  Authorization Load (0.8ms)  SELECT  "authorizations".* FROM "authorizations" WHERE "authorizations"."id" = $1 LIMIT $2  [["id", 4], ["LIMIT", 1]]
  ↳ app/controllers/authorizations_controller.rb:67
  Rendering authorizations/show.html.erb within layouts/application
  Rendered authorizations/show.html.erb within layouts/application (3.2ms)
Completed 200 OK in 89ms (Views: 77.5ms | ActiveRecord: 3.1ms)

Upvotes: 0

Views: 301

Answers (1)

max
max

Reputation: 101891

Do not use attr_accessor for database backed attributes in ActiveRecord.

Not only is it completely superfluous it also overrides the getters and setters that ActiveRecord creates from your database schema which are required for AR to work properly.

The end result as you can see is that the model just takes the attributes and does nothing with them. Just like the instance variables of a plain old ruby object.

Also you should bind the attributes in your controller and not in the form as you are unintendly breaking the form (setting the inputs to nil) when it is rendered from the create action.

class AuthorizationsController < ApplicationController
  before_action :set_authorization, only: [:show, :edit, :update, :destroy]
  # ...

  # GET /authorizations/new
  def new
    @authorization = Authorization.new(
      params.permit(:name, :email, :type_of_booking, :booking_id, :price)
    )
  end
end

Upvotes: 2

Related Questions