views:

31

answers:

2

Hello there, I'm trying to override the way rails apply and id to an associated object, for example:

There are 2 simple models:

class Album < ActiveRecord::Base
  has_many :photos
end

class Photo < ActiveRecord::Base
  belongs_to :album
end

And then I want to do this:

album = Album.new :title => 'First Album'
album.photos.build
album.save #=> true

On this case I've created a plugin that overrides the id property and replaces it to a hashed string, so what I want to do is find the methods where this album_id is being replaced for my custom method instead of the int and be able to converted before it's saved. But I want to act globally inside Rails structure because since it will be a sort of plugin I want to make this action work on dynamic models, that's why I can't create an before_save validation on the model.

I'm not sure if it's easy to understand, but I hope someone could help me on that..

Here's a screenshot of my current table so you can see what is happening:

SQLite3 DB

So as you can see the album_id it's being replaced for my custom ruby object when its saved...I've disabled the plugin and then it saved normally with records 11 and 12...

I want just act on a rails action and converted with my custom methods, something like

def rails_association_replaced_method(record)
   #take the record associations and apply a to_i custom method before save
   super(record)
end

something like this :)

Well I hope this didn't get too complicated

Cheers

A: 

Rails is unfriendly to that kind of change to the defaults. What's your end goal here?

Joe Martinez
Hi Joe, actually I'm converting the IDs over my application to a hashed version they are encoded once you try `Photo.first.id #=> e3fD` and decoded to its original value once you use `Photo.first.id.to_i #=> 10`, I'm not sure if there is any method that I can configure to override this `--- !ruby/object:Shortener::Result` representation to what I want, there's the `inspect` method which works for certain cases but unfortunately not for this one. :(
ludicco
Are you doing this to generate file paths or something? You may want to look at just overriding #to_param and leaving the keys as integers in the database.
Joe Martinez
Hi Joe, actually this is supposed to replace all the IDs interpretation over the app, the `to_param` method only seems be helpful for generating urls but not for converting it back, maybe I'm wrong.
ludicco
You're right about that. I guess I just don't understand why you're trying to do this.
Joe Martinez
+1  A: 

It seems if I only override theActiveRecord::Base save method do the job if handled properly

define_method 'save' do
  int_fields = self.class.columns.find_all { |column| column.type == :integer }
  int_fields.each do |field|
    if self.attributes[field.name]
      self.attributes[field.name] = self.attributes[field.name].to_i
    end
  end
  super
end

And this shall replace all the integer fields from the Current Model applying a to_i method over the result.

ludicco