Rails: Tableless model that calls other models - ruby-on-rails

I have a Rails app with a few model classes (e.g. Category, Subcategory, User, etc.). In order to implement a not-too-trivial filter functionality, I built a hierarchy of filter classes: FilterCategory, FilterSubcategory, etc., that derive from FilterBase. Each of them uses the appropriate "sister" model class (e.g. Category.find :all).
I quickly realized that I can't simply call the "sister" model class without using "require" first. However, I now suspect that using "require" is the main reason for two other problems I posted here and here, which probably mess up the class caching when config.cache_classes=false.
Is there another way for me to call these other models without requiring them?
I tried using the BaseWithoutTable plugin, but when I call the "sister model", I end up getting "Not a valid constant descriptor: nil", which occurs since Rails looks for "FilterCategory::Category" rather than "Category".
Any thoughts of the best way to do that?
I'm using Rails 2.3.8, Ruby 1.8.7.
Thanks,
Amit

I wonder if you want ::Category - getting Category from the top-level namespace rather than scoping it to FilterCategory?
If your models are in the app/models directory, you shouldn't need to explicitly require them - Rails already takes care of that.

Related

Rails create! using wrong class

I have two models Plan and Student::Plan. When calling Student::Plan.create! in my seeds.rb file I get back a Plan object. It seems as though rails is getting confused by the namespacing or something. Any thoughts that don't involve renaming the class?
file structure
models
plan.rb
student
plan.rb
tables
plans
student_plans
Update
This gets even weirder when testing w/ rails c. If you call Student::Plan.create! first then you'll get the expected object back. If you instead call Plan.create! and then Student::Plan.create! you'll be back a Plan object instead of what you'd actually expect.
Works
Student::Plan.create # <Student::Plan...>
Doesn't Work
Plan.create # <Plan...>
Student::Plan.create # <Plan...>
I can imagine a scenario where you have namespaced models (I've used it a few times...usually for integrating different db's). And this answer doesn't get to the issue of dealing with namespacing issues, but I do think the "Judo" solution is to just create a model called student_plan.rb at the root of the models directory, and use StudentPlan.create and Plan.create respectively.

How to manually load all classes inside rails application?

How to load & get collection of all active-record models used inside rails app.
It should give classes from gems, plugins as well as subclasses having active-record base in parent hierarchy.
ActiveRecord::Base.descendants.collect(&:name)
gives me list but its only after all classes gets loaded.
Is there any way to load all classes inside rails app manually ?
The problem with Ruby is that "all classes" is a somewhat difficult thing to ascertain. Some of them may be generated dynamically and conditionally.
Sometimes you can just load what's present in app/models:
Dir.glob(File.expand_path("app/models/*.rb", Rails.root)).each do |model_file|
require model_file
end
If there's other locations that may contain models you'll need to include those, too.
You might have dependencies, though, and that can preclude model A from loading before model B. This is why the autoloader is used by default and things just aren't loaded in.
The only reliable way to get them all loaded is to somehow exercise them all at least once.
Getting model list based upon db tables -
ActiveRecord::Base.connection.tables.collect{|t| t.singularize.camelize.constantize rescue nil}.compact

Rails: FakeModel runs the same validation too many times

We have created a FakeModel object class which inherits from Object,
to allow working with models who don't have a DB table.
It has the basic functionality of a regular ActiveRecord model.
We also added in the class the following line:
include ActiveRecord::Validations
The problem is this:
A new request is sent to the controller, and creates a new object inheriting from the FakeModel class.
When the validations of that object run, they run more then once.
Too be more specific - with each request sent to the server,
the validations run one time more than the last request.
I'm guessing something here "sticks" on the server-level
(of course, when I restart the server, it resets back to running the validations just once)
What can be the cause of that?
UPDATE :
The ActiveModel solution isn't possible for me because I'm using Rails 2.3.8. I still need to figure out where is the problem.
I would suggest you to use ActiveModel instead of writing your own Model engine from scratch, see this blog post for a tutorial you can also watch this screencast
I'm stabbing the dark here, but it sounds like the validations keep being included every time the model is loaded/saved.
Can you show us where you include it?
In Hyperactive Resource, instead of include we used:
# make validations work just like ActiveRecord by pulling them in directly
require "active_record/validations.rb"
extend ActiveRecord::Validations::ClassMethods

Rails naming conventions for models with forbidden names

I'm writing a rails application, and I need to name one of my model Test, and inside that model I need a class attribute - when I tried the first one, I couldn't run any UT since Test ceased to be a module - so I ranamed to Tst. I haven't even tried naming a column class - I went with clss. What names would you use? Are there any conventions known amongs RoR developers for such situations?
I haven't seen anything for Test but class is typically changed to klass.
Ruby and Rails have several different objects part of a standard library. You cannot use an already-defined class name as name for your models.
For instance, you cannot call a model Thread or Object because Ruby already defines a Thread and Object class.
Likewise, Ruby has a library called Test::Unit so you can't use the Test namespace as model name.
There isn't a real full list of reserve objects because it really depends on your current environment. However, in order to successfully use Rails, you should at least have a basic Ruby knowledge so that you know the names of the most common standard library classes.
I've run up against this a few times (writing educational software--where you regularly want to model 'tests' :-). Depends exactly what you're modeling I suppose, but I usually opt for 'quiz' to avoid conflicts. I'd love to hear a better solution, since I find 'quizzes' an awkward plural.
Like dj2 said, class is usually done as 'klass'.
Please check the following page for Rails reserved words: http://reservedwords.herokuapp.com/ None of these words should be used as class or attribute name.

rails model using class hierarchy from an external gem?

I'm working on a project where the data model is :
implemented in a separate gem
does not use ActiveRecord, nor any relational database storage ( actually it relies on couchdb )
makes usage of namespaces
makes intensive usage of class inheritance
To simplify the schema, let's say we have the following root class :
module Marketplace
module Food
class Fruit
…
end
end
end
And a couple of specialized classes :
module Marketplace
module Food
class Peach < Marketplace::Food::Fruit
…
end
class Tomato < Marketplace::Food::Fruit
…
end
end
end
I'd like Rails to display (and manage) all the Fruits whatever is their nature, without modifying the model witch works perfectly out of Rails.
The issue is that ActionView seems to use a certain number of conventions for defining paths and urls that will be based on the real class names.
So if I present an Apple, in a table with show/delete actions, rails will look for a methods named marketplace_food_apple_path and similar which of course don't exist.
Is there a way to indicate the ActionView::Base structure(s) that an Apple is a Fruit ?
I'd expect this 'base cast' to be 'trivial' for a framework based on Ruby but it seems that this simple example of object oriented model does not work with Rails ?
How do you manage 'complex object' data models in rails ?
Or it is simply out of scope of Rails ?
Thanks for any pointers !
http://railstips.org/blog/archives/2009/05/15/include-vs-extend-in-ruby/ <-- probably what you want, unless you're just looking to argue the single inheritance versus multiple inheritance strawman.
OK as I see there are plenty of useful answers ;).
It basically confirms my doubts on Rails which I see more like a sort of VB : easy to learn, nice for small things (shopping or community sites) but very limited.
Rails is completely out of scope when it gets to handling complex business logic and data !
As Rails 3.0 does not seem to be the answer neither (ok we have several ORM's but we're still unable to use inheritance in the model) I switched to Ramaze, a small framework that makes no assumptions on how the data is organized making it suitable for almost any kind of web needs.
If you are facing model constraints with Rails, maybe you should forget about Rails and check Ramaze !

Resources