Search code examples
ruby-on-railsruby-on-rails-3activerecordopenwisp

Rails Active Record, how to have an additional field parameter in the result of a query?


I actually have this model:

class Role < ActiveRecord::Base
  acts_as_authorization_role

  def self.all_join_wisp
    self.connection.select_all("SELECT roles.*, wisps.name AS wisp_name FROM roles LEFT JOIN wisps ON wisps.id = roles.authorizable_id")
  end
end

the method all_join_wisp does almost what I want, it adds the field wisp_name, except it return a hash and not an active record object.

Is there a way to retrieve an active record object instead?

The Role model does not have belongs_to and the wisp model does not have has_many :roles , I guess it was done for flexibility or something (I did not develop the application I'm working on).

Edit: Solution implemented

Solution implemented here: https://github.com/nemesisdesign/OpenWISP-Geographic-Monitoring/blob/287861d95fffde35d78b76ca1e529c21b0f3a54b/app/models/role.rb#L25 Thanks to @house9


Solution

  • you can use find_by_sql - you get back what looks like an activerecord object but isn't really, it will have attributes from your query but they will all be string data types instead of the real types, often this is ok

    def self.all_join_wisp
      self.find_by_sql("SELECT roles.*, wisps.name AS wisp_name FROM roles LEFT JOIN wisps ON wisps.id = roles.authorizable_id")
    end
    

    then

    list = Role.all_join_wisp
    list.each do |x|
      puts x
      puts x.inspect
      puts x.id # the role id 
      puts x.id.is_a?(Integer) # false
      puts x.id.is_a?(String) # true
      puts x.name # the role name
      puts x.wisp_name # wisp name, NOTE: Role does not really have this attribute, find_by_sql adds it
    end