Showing posts with label active record. Show all posts
Showing posts with label active record. Show all posts

Tuesday, January 17, 2012

Get models list inside rails app

by sandipransing 0 comments
How to get collection of models inside your application. Certainly there are many ways to do it.
Lets have a look at different ways starting from worst -
Get table names inside database and then iterating over to get model name @models = ActiveRecord::Base.connection.tables.collect{|t| t.underscore.singularize.camelize} #=> ["AdhearsionAudit", "AudioLog", "AuditDetail","TinyPrint", "TinyVideo", "UnknownCall", "UserAudit", "User"]
Select those with associated class
@models.delete_if{|m| m.constantize rescue true}
Load models dir
@models = Dir['app/models/*.rb'].map {|f| File.basename(f, '.*').camelize.constantize.name } Select ActiveRecord::Base extended class only @models.reject!{|m| m.constantize.superclass != ActiveRecord::Base } Get Active Record subclasses
# make sure relevant models are loaded otherwise # require them prior # Dir.glob(RAILS_ROOT + '/app/models/*.rb').each { |file| require file } class A < ActiveRecord::Base end class B < A end ActiveRecord::Base.send(:subclasses).collect(&:name) #=> [...., A] How to get Inherited models too
class A < ActiveRecord::Base end class B < A end ActiveRecord::Base.descendants.collect(&:name) #=> [...., A, B] Below is more elegant solution provide by Vincent-robert over stack overflow which recursively looks for subsequent descendent's of class and gives you list from all over application
class Class def extend?(klass) not superclass.nil? and ( superclass == klass or superclass.extend? klass ) end end def models Module.constants.select do |constant_name| constant = eval constant_name if not constant.nil? and constant.is_a? Class and constant.extend? ActiveRecord::Base constant end end end
Read More…

Wednesday, December 28, 2011

Simplified Active Record Extensions

by sandipransing 0 comments
Below extensions to active record base simplifies its usage while coding.
# config/initializers/core_extensions.rb class ActiveRecord::Base def self.pagination(options) paginate :per_page => options[:per_page] || per_page, :page => options[:page] end def self.options_for_select(opts={}) opts[:name] ||= :name opts[:attr] ||= :id opts[:prompt] ||= 'Please Select' all.collect{|c| [c.send(opts[:name].to_sym), c.send(opts[:attr].to_sym)]}.insert(0, [opts[:prompt], nil]) end end Usage
class Student< ActiveRecord::Base #attributes #=> name, age end ## Student.pagination({:page => 10}) Student.pagination({:per_page => 2, :page => 2}) Student.options_for_select Student.options_for_select({:prompt => 'Please select'}) Student.options_for_select({:name => :age})
Read More…

Thursday, December 22, 2011

Best practices to use named scopes inside models

by sandipransing 0 comments
Scopes are partial query conditions to database queries. scopes are always prefixed to class finders. There are several ways to use scopes inside rails models. # 1. Scope defined below gets loaded while class definition loads scope :active, where(:active => true) scope :archived, where(:archived => true, :post_type => :general) # 2.Dynamic scopes needs to be always defined inside lambda scope :not_expired, lambda { where('expiry_date <= ?', Date.today) } # 3.Combining scopes scope :visible, published.not_expired
# 4. Passing parameters to scopes # avoid below scope :created_by_user, lambda {|user| where('user_id = ?', user) } # use this scope :created_by_user, lambda {|user| where(:user_id => user) }
# 5. passing multiple parameters # avoid below scope :made_between, lambda{|from, to| where('created_date >= ? and created_date <= ?', from, to) } # use this scope :made_between, lambda{|from, to| where('created_date >= :from and created_date <= :to', :from => from, :to => to) }
# 6. associations inside scope (joins and includes) # below will perform eager loading effective when rendering posts with comments scope :with_user_comments, lambda{|user| includes(:comments).where('comments.user_id = ?', user) } # faster # also can be done as post.comments.where(:user_id => user) scope :with_user_comments, lambda{|user| joins(:comments).where('comments.user_id = ?', user) }
So, at last would suggest making use of symbols when there are multiple parameters to scopes and make maximum use of scopes rather than having where conditions everywhere :)
Read More…

Wednesday, October 5, 2011

Legacy database connections in rails

by sandipransing 0 comments
While developing rails application we often come across situation where you wanted different rails models connecting different tables of different databases.
Example: We are having ndnc model holding ndnc records associated with database ndnc.
Lets create ConnectionBase model that will connect to other databse 'ndnc' and that will be extended from ActiveRecordBase and put that inside library files
vi lib/connection_base.rb class ConnectionBase < ActiveRecord::Base establish_connection( :adapter => "postgresql", :username=> "sandip", :password => "2121", :database => "ndnc" ) end

Wherever you wanted to connect to other database i.e. ndnc you can extend that particular model with ConnectionBase
class Ndnc < ConnectionBase # connects to ndnc table of ndnc database end
Please make sure library files are loaded while server startup
# vi config/application.rb config.autoload_paths += %W(#{config.root}/lib)
Done !
In cases where you want only one particular model connecting other database table, you can put connection setting itself in that model.
Read More…

Monday, February 15, 2010

ActiveRecord::ReadOnlyRecord while updating object fetched by joins

by sandipransing 0 comments
ActiveRecord find with join options retrieves object as readonly
station = Station.find( :first, :joins => :call, :conditions => ["customer_id = ? and date(insurance_expiry_date) = ?", customer.id, insurance_expiry_date ] )
Readonly object cannot modified and hence below line raises "ActiveRecord::ReadOnlyRecord" error.
station.update_attributes({ :customer_id => 12 })
If you have to write on read only object then you can pass following option to find query
:readonly => false
Now below find is permitted to do write on fetched object records.
station = Station.find( :first, :joins => :call, :conditions => ["customer_id = ? and date(insurance_expiry_date) = ?", customer.id, insurance_expiry_date ], :readonly => false )
Read More…

Thursday, November 26, 2009

How to get all associated models of rails model

by sandipransing 0 comments
I have Site Model and i wanted to find all associated models of Site model which are having belongs_to relationship. After doing lot headache, here is the solution i found


has_many models of Site Model
 Site.reflect_on_all_associations.map{|mac| mac.class_name if mac.macro==:has_many}.compact
=> ["Layout", "User", "SubmenuLink", "Snippet", "Asset"]

belongs_to model of Site Model
Site.reflect_on_all_associations.map{|mac| mac.class_name if mac.macro==:belongs_to}.compact
=> ["User", "Page", "User"]

To get all associations
Site.reflect_on_all_associations.map{|mac| mac.class_name}.compact
=> ["Layout", "User", "Page", "User", "SubmenuLink", "User", "Snippet", "Asset"]

Hari, U rocks !
Read More…

Thursday, November 12, 2009

Manual active record db connection in ruby using mysql adapter

by sandipransing 2 comments
Below is ruby code to establish manual database connection.
require 'active_record' ActiveRecord::Base.establish_connection( :adapter => "mysql", :host => "localhost", :username => "root", :password => "abcd", :database => "funonrails" )
Snippet of database.yml file
common: &common adapter: mysql database: students_dev username: root password: host: localhost students_development: <<: *common database: students_dev students_production: <<: *common database: students
Load database configurations from yml file
dbconfig = YAML::load(File.open('database.yml')) ActiveRecord::Base.establish_connection( dbconfig[:students_development] )
Active Record Model & DB connection
class Student < ActiveRecord::Base establish_connection "students_production" set_table_name "student" set_primary_key "stud_number" end
Read More…

Wednesday, October 21, 2009

How to map irregular database tables with rails models

by sandipransing 2 comments
Rails specifies conventions while creating models, controllers, migrations ( database tables ).

Conventions for creating database tables
1. Table name should be plural
2. id field should be primary_key for table.
3. foreign_key should be like _id i.e. post_id, site_id

Conventions for creating models & Controllers
1. Model name should be singular
2. controller name should be plural.
Although rails has standard defined, In some cases it becomes quite necessary to map irregular

1. Table mapping
class Review < ActiveRecord::Base # Here comments is name of database table set_table_name :comments end
2. Set primary key ( other than rails standar 'id' primary_key )
class Review < ActiveRecord::Base # It assumes "reviews" as table in database # Below line indicates reviews table contains column_name "reviewId" which is a primary_key set_primary_key :reviewId end
3. Foreign key association
class Review < ActiveRecord::Base # Below line indicates reviews table contains column_name 'RatingId' which is foreign_key to primary_key # of 'ratings' table. # It can be applied to any associan type [ has_one, has_many, belongs_to, has_many_through ] belongs_to :rating, :class_name => "SiteUser", :foreign_key => "RatingId" end
4. Model association ( non-standard model name )
class Review < ActiveRecord::Base # Below line indicates reviews table contains column_name 'UserId' which is foreign_key to primary_key # of model with class_name 'SiteUser' belongs_to :user, :class_name => 'SiteUser', :foreign_key: => 'UserId' end
Read More…

About The Author

Sandip is a ruby on rails developer based in pune and also a blogger at funonrails. Opensource contributor and working with Josh software Private Limited. for more info read Follow Sandip on Twitter for updates.

Connect With Me...

Github Projects

@sandipransing Twitter