I have several apps that share common base models which I am coding into a plugin, but each app may need to add some additional code or override some code in the plugin model. One of the main differences is that I use multiple database servers in alot of these apps, which is managed by the "use_db" plugin. I am trying to figure out a way to use the "use_db" plugin without hard coding it into the plugin class. I dont want to have to change the plugin every time I install it in a new app. Can anyone think of a way to create a class inside the rails directories that would be able to extend the plugin model and also be able to specify my "use_db" database... overriding the default rails database. I would also need to be able to add new methods and override methods contained in the plugin model. The model in the plugin contains lots of associations, named_scopes, etc.. so that stuff would still need to be active in the extended model... so I dont think a module would work. For those not familiar with "use_db" it just allows you to include a prefix which is pulled from database.yml, and the model will use this database. Example: class Widget < ActiveRecord::Base use_db :prefix => "slave2_" end this would use the database config "slave2_production" in database.yml for that model if you are in prod mode. I have tried using "extends" inside the class, creating a subclass, etc.. but nothing seems to give me the behavior I desire. Any ideas guys? Thanks in advance! -- Posted via http://www.ruby-forum.com/. -- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.
I have the same issue. Have you been able to figure it out? Thanks, Maher -- Posted via http://www.ruby-forum.com/. -- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.
Maher Hawash wrote:> I have the same issue. Have you been able to figure it out? > > Thanks, > MaherI moved on to other work after I posted this. I will probably revisit this week. I will let you know what I figure out. There has to be an elegant way to do this. I really just need to learn more about the object-oriented side of Ruby works... reading about it now. -- Posted via http://www.ruby-forum.com/. -- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.
On 26 February 2010 17:35, Yanni Mac <lists-fsXkhYbjdPsEEoCn2XhGlw@public.gmane.org> wrote:> I have several apps that share common base models which I am coding into > a plugin, but each app may need to add some additional code or override > some code in the plugin model. >OK, so let''s assume your base model is like this: class MyPlugin:: Widget::Base < ActiveRecord::Base ... some code ... end> One of the main differences is that I use multiple database servers in > alot of these apps, which is managed by the "use_db" plugin. I am > trying to figure out a way to use the "use_db" plugin without hard > coding it into the plugin class. I dont want to have to change the > plugin every time I install it in a new app. >OK, so then in your app you declare a model as: class Widget < MyPlugin:: Widget::Base use_db :prefix => "slave2_" end Alternatively, if you want to declare a User class in your plugin and have your app use that if it''s found, why not just create an initializer in your application. As you can read here - http://railsguts.com/initialization.html - plugins are loaded before application initializers, so you could put a file in your config/initializers folder that just does: class Widget use_db :prefix => "slave2_" end The Widget class could already have been defined from your plugin initializer, so you''re then just re-opening the class and adding your use_db. Can anyone think of a way to create a class inside the rails directories> that would be able to extend the plugin model and also be able to > specify my "use_db" database... overriding the default rails database. > I would also need to be able to add new methods and override methods > contained in the plugin model. The model in the plugin contains lots of > associations, named_scopes, etc.. so that stuff would still need to be > active in the extended model... so I dont think a module would work. >I''m not sure I follow you. However, you could do the above with the config/initializers to open your defined plugin class and add your functionality. If you want you could just do a simple require within the config/initializer/widget.rb file that loads the file from within app/models (which may be a better place for your modifications). require Rails.root.join("app", "models", "widget") The reason for this is that you can''t just re-open the class within app/models/widget.rb as that file will only be opened if the class isn''t defined (it''s an autoloading path, not an "open every file in this path at boot time" path), so you need to specifically load it from an initializer/environment file.> I have tried using "extends" inside the class, creating a subclass, > etc.. but nothing seems to give me the behavior I desire. Any ideas > guys?If you can flesh out your requirement/desires a bit more fully I''ll happily work up a solution with you, but I''m going on guesswork a bit at the moment :-) Cheers, Andy -- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.
Andy, thank you very much for the reply. If I can get the first solution to work, I think I would prefer that. I have been playing around with the code and I am getting errors saying my model class (in rails dir) should define Widget. So is it even possible to use Widget as the name in the plugin Base model and at the same time have a rails model with the same name using it as a subclass? class Widget < MyPlugin:: Widget::Base I was thinking I could just rename the base class to BaseWidget, but then rails is looking for that database name (base_widgets) when it loads widget since its an activerecord subclass. Thanks for your help! -- Posted via http://www.ruby-forum.com/. -- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.
> > Andy, thank you very much for the reply. If I can get the first > solution to work, I think I would prefer that. I have been playing > around with the code and I am getting errors saying my model class (in > rails dir) should define Widget.This normally means that you have a file named "widget.rb" but don''t define a class called "Widget" in it. The class name/file name must match (except for the conventional conversion to camelcase from underscores) for Rails to be able to find/autoload it.> So is it even possible to use Widget > as the name in the plugin Base model and at the same time have a rails > model with the same name using it as a subclass?Yes. You could even use the same class name, Ruby let''s you re-open a class and add new methods to it or change existing ones. But you can certainly have a base class declared in your plugin and have a specific class inherit from that in your app.> class Widget < MyPlugin:: Widget::Base > > I was thinking I could just rename the base class to BaseWidget, but > then rails is looking for that database name (base_widgets) when it > loads widget since its an activerecord subclass. >Oohhh that''s a good point. You may have to name your plugin class as MyPlugin::Widget as I don''t think ActiveRecord supports namespaced classes to tables out of the box (I remember adding code to a Rails project a while ago because I WANTED it to do that, but it may have changed by now). However, from a quick play it seems that ActiveRecord doesn''t look for the database table unless you actually use it, and you shouldn''t be using your BaseWidget class but a subclass of it (correctly named to match the table).> Thanks for your help! >No worries, keep posting back with what you have and what''s going wrong until it''s solved; I''m sure we''ll be able to get you running... Cheers, Andy -- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.
Andy, Thanks for all your responses. This helped me do some additional research. I found something that works perfectly for my scenario. Using mixin modules. http://weblog.jamisbuck.org/2007/1/17/concerns-in-activerecord I tried using mixins earlier today, but I was not able to use the associations, named_scope, etc. But you can add self.included(base) around all the AR associations, etc. and this will load them into your model class. Here is my final setup which is working well so far: #----------------------------------------------------------- # /my_rails_app/vendor/plugins/my_plugin/lib/base_widget.rb # ---------------------------------------------------------- module BaseWidget def self.included(base) base.named_scope :expensive, :conditions=>"price>100" base.belongs_to :manufacturer end def formatted_price "$"+self.price.to_s end end #----------------------------------------------------------- # /my_rails_app/app/models/widget.rb # ---------------------------------------------------------- class Widget < ActiveRecord::Base include BaseWidget use_db :prefix => "slave2_" end -- Posted via http://www.ruby-forum.com/. -- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.
Additionally, you can include a default class in your plugin. This would give you the model out of the box when you install the plugin, so you don''t even have to create a model in /app/models/ #----------------------------------------------------------- # /my_rails_app/vendor/plugins/my_plugin/widget.rb # ---------------------------------------------------------- class Widget < ActiveRecord::Base include BaseWidget end Then if you have additional functionality you need to add (like use_db), you just drop a class into /my_rails_app/app/models/ and it will use that one instead of the default class that is contained in the plugin. -- Posted via http://www.ruby-forum.com/. -- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.
Yanni Mac wrote:> Additionally, you can include a default class in your plugin. This > would give you the model out of the box when you install the plugin, so > you don''t even have to create a model in /app/models/ > > #----------------------------------------------------------- > # /my_rails_app/vendor/plugins/my_plugin/widget.rb > # ---------------------------------------------------------- > class Widget < ActiveRecord::Base > include BaseWidget > end > > > Then if you have additional functionality you need to add (like use_db), > you just drop a class into /my_rails_app/app/models/ and it will use > that one instead of the default class that is contained in the plugin.One gotcha.. rails gets confused in certain situations and will throw a Dup error. You need to add "unloadable" to the top of the model class. class Widget < ActiveRecord::Base unloadable include BaseWidget end -- Posted via http://www.ruby-forum.com/. -- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.