views:

425

answers:

3

I know this is going against ruby on rails conventions, but my id of this table doesn't need to auto-increment and I'm setting it through the logic. However, it's not saving to the database. Everything getting saved is saving as null for the id.

def self.up
 create_table :probes, :id => false do |t|
  t.string :id
  t.string :name
  t.integer :user_id
  t.boolean :online
  t.timestamps
 end
end

<% form_for @probe do |f| %>
<%= f.error_messages %>
 <p>
  <%= f.label "Site name" %><br />
  <%= f.text_field :name %>
 </p>
     <p style="margin-left: 10%">
  <%= f.label "Probe Key" %><br />
  <%= f.text_field :id, :value => @token %>
 </p>
 <p style="margin-left: 20%">
  <%= link_to "Back to List", probes_path %>
  <%= f.submit "Submit",:style => "margin-left: 75px;" %></p>
 <% end %>

Is this even possible? Or is there somewhere besides the new.html.erb file that I should be changing/checking?

A: 

I'm pretty sure that ActiveRecord instances are set up so that the id attribute cannot be set through mass-assignment which is typically how you'd create an object through a form like that. If you look in your logs you may see a warning saying something along these lines.

If you set the id specifically rather than using something like p = Probe.new(params[:probe]) then you should be okay. E.g.

p = Probe.new(params[:probe])
p.id = param[:probe][:id]
Shadwell
+1  A: 

the :id field is not accessible for mass-assignment. you need to set it manually with

@probe.id = params[:probe][:id]

in your controller code.

(It also might work if you add :id to your attr_accessible list, and in general you should set attr_accessible for every model that is directly mass-assigned from form parameters, but w/o testing I'm not sure if it will work, you might still have to manually set :id)

Vitaly Kushner
I have @Probe = Probe.new(params[:probe]) @Probe = params[:probe][:id] In my controller, but still not working. Here is my entire create method: def create @user = current_user @probe = Probe.new(params[:probe]) @probe.id = params[:probe][:id] @probe = @user.probes.create!(params[:probe]) if @probe.save flash[:notice] = "Successfully created probe." redirect_to probes_path else render :action => 'new' end end
Ryan
Well, i'm retarded, haha. I forgot to pass in @probe in the create method. However now i'm getting an error about strigify keys...undefined method `stringify_keys!'
Ryan
And that was happening because i was using create which only accepts a hash. @Probe.save worked fine. Problem fixed.
Ryan
Nope, attr_accessible doesn't work. Only direct assignment, f*ck it.
Nikita Rybak
+1  A: 

From AdminMyServer on http://stackoverflow.com/questions/517869/id-field-without-autoincrement-option-in- migration

#using a number
create_table(:table_name, :id => false) do |t|  
  t.integer :id, :options => 'PRIMARY KEY'
end

#using as string, like the question (why?)
create_table(:table_name, :id => false) do |t|  
  t.string :id, :options => 'PRIMARY KEY'
end
Tim Hoolihan
This is integer, rails doesn't like non-numeric primary keys. At least that's what I'm reading. Is there a way to set a string as a primary key?
Ryan
i didn't notice you were using string... is there a good reason why?
Tim Hoolihan
The ID is a UUID generated, and I'm doing this because belongs_to can't have a primary key which I need, so I'm making this the ID so I can join my tables together correctly.
Ryan