2

I have a MySQL database table with the following simplified schema:

create_table "sensors", force: :cascade do |t|
  t.integer  "hex_id",     limit: 8, null: false
end

where hex_id is declared as a BIGINT in MySQL. I would like for the user to type in a hexadecimal value, then convert it to base 10 and save it in hex_id. To accomplish this, I thought I would create a virtual attribute called hex to store a hexadecimal string of characters. My Sensor model looks like this:

class Sensor < ActiveRecord::Base  
  attr_accessor :hex

  validates :hex, presence: true

  before_create :hex_to_bigint
  before_update :hex_to_bigint

  private
  def hex_to_bigint
    self.hex_id = hex.to_s(10)
  end
end

and the controller is using standard rails-generated code:

  def new
    @sensor = Sensor.new
  end

  # POST /sensors
  def create
    @sensor = Sensor.new(sensor_params)

    if @sensor.save
      redirect_to @sensor, notice: 'Sensor was successfully created.'
    else
      render :new
    end
  end

I created a view with a form that uses the hex attribute.

<%= f.label :hex do %>HEX ID:
    <%= f.text_field :hex, required: true, pattern: '^[a-fA-F\d]+$' %>
<% end %>

When I click submit, the params array has the following contents:

{"utf8"=>"✓", "authenticity_token"=>"some_long_token", "sensor"=>{"hex"=>"E000124EB63E0001"}, "commit"=>"Create Sensor"}

My problem is that the attribute hex is always empty, and my validation fails. There are many resources on the web that explain how to use virtual attributes, but very few that explain how to use them in conjunction with ActiveRecord. I have spent hours looking for a way to solve this rather simple problem but have found nothing that works. Any help is appreciated. My ruby version is 2.0.0p481. Thanks!

Vadim
  • 1,916
  • 2
  • 19
  • 39
  • please post your controller code and params which you are getting after clicking on save or update – Amit Sharma Apr 12 '15 at 20:42
  • You have written `:hex_to_bigint` method in 2 callbacks ie. create and update.You can do it in 1 callback also just write following code `before_save :hex_to_bigint` then it will work for both. – Amit Sharma Apr 12 '15 at 20:45
  • Thanks for the top, @AmitSharma, I've changed my `Sensor` model to use `before_save`. I have also added the controller code and the contents of `params`, as requested. – Vadim Apr 12 '15 at 23:55
  • have you added `hex` in permitted params? – Amit Sharma Apr 13 '15 at 06:49
  • please also post permit params mehod – Amit Sharma Apr 13 '15 at 06:49
  • I've added `:hex` to `params.require(:sensor).permit(:hex_id, :hex)` as you said, and it all magically started to work!!! I thought that would not help because `hex` is a virtual attribute, and `params.permit` only takes `ActiveRecord` attributes. Clearly, I was wrong. Thank you so much! Please add your comment as an answer, and I will accept it as correct. – Vadim Apr 15 '15 at 02:17
  • I have added the answer please accept. – Amit Sharma Apr 15 '15 at 12:09

1 Answers1

2

Please add hex in permitted params. see the code below

private

# Never trust parameters from the scary internet, only allow the white list through.
def sensor_params
  params.require(:sensor).permit(:hex_id, :hex)
end

I hope this will help you

Amit Sharma
  • 3,427
  • 2
  • 15
  • 20