I'm using Rails 3.1 on a project, and bundler has added quite a few gems that I do not really know the contents of that well.
For some reason in development mode (probably because it keeps unloading classes), I intermittently run into an ActiveRecord::AssociationTypeMismatch. That look like this:
Character(#31360520) expected, got Character(#23815500)
I believe that one of the gems has defined a class "Character" and it's conflicting with my ActiveRecord "Character" model. I'm having trouble searching down the source of this problem as it comes up with a bunch of generic results, and I'm not sure what those numbers are called by the Ruby community (class id?).
So a few questions that I'd love help with:
what is that number in the parens after the class name?
How can I look up where that class is from (in which gem) based on the id reported in the exception?
What is the best practice here for commonly named ActiveRecord models? Should I be namespacing my models, or is the blame more with the author of the gem?
i'm sort of a noob, so don't consider all i say as an established truth - but i think i might help.
question 1
Not sure, but i suspect those numbers are object_ids of the expected Class. In ruby, classes are objects too (singleton objects, though), so they have an object_id as would any other object (you can call object_id on any object to get its unique id). If you want to get an Hash of every classes loaded in your environment along with their id, you can try something like this in the console :
all_classes = ObjectSpace.each_object.select {|o| o.class == Class}
with_ids = Hash[ all_classes.map {|c| [c,c.object_id] } ]
question 2
In the console, all classes are displayed showing their full namespace path, so you should be able with the above script to distinguish your two Character classes if they belong to a different namespace.
If the namespace is identical though, the problem may become hairy because one of your class definition will override the other, depending on the load order. I would not be surprised if using ri in your shell would help you to find the culprit gem in this case.
question 3
I would say : avoid vague, too common names for your models ; but in this case, i'd say the gem is to blame, because someone providing a gem should be really careful not to pollute the namespace, especially if it pollutes the ActiveRecord::Base namespace.
Related
I have a project with class Matrix < ActiveRecord::Base, and I'm hitting situations where Matrix.where is crashing because it's trying to access the Matrix < Enumerable class from ruby.
Is there a way to specify which Matrix I want, like ActiveRecord::Base::Matrix?
I know I could rename the model, but it would be a pain (old spaghetti project)
Rename it or be forever battling Ruby core. You can't get around this. Rails chose to put model names in the root namespace as it's very convenient, but leads to problems when that conflicts with either Rails or Ruby.
Solutions:
Try and force-load your model before the Ruby Matrix has a chance to usurp it
This may have unintended consequences (like a crash) should require 'matrix' show up somewhere
This could also mess up gems that expect Matrix to be the Ruby thing and not your random model
Move it into a namespace like MyProject::Matrix
Rename it to something dumb like MMatrix as a reminder that this name was a bad idea from the outset
The good news is that if this is a fairly unique string, then a global replace of Matrix to the alternate name is probably not going to be that bad.
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.
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.
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 !
I'm new to Ruby and recently ran into an issue comparing to values when creating a Ruby on Rails application. In a controller I had the following statement that always returned false:
if (user.id != params[:id])
The problem was the user.id (which is an Active Record) is an integer and params[:id] is a string. It took me a while to figure this out and I finally changed it to:
if (user.id != params[:id].to_i)
Now the statement works as expected.
To avoid this error in the future is there a way to "compile" or get Ruby to warn you if you try to compare 2 different types? Some other issues I've ran into that I would like to "compile check" are:
Warn me if I create a variable but don't use it. To help check for typos in variable names.
Make sure a method exists in a Class so I can avoid method name typos and also to help refactoring, for example if I rename a method.
I'm currently using Ruby 1.8.6-27 RC2 with Rails 2.3.2 and RadRails IDE on Windows.
Test first, then code. If you write tests that cover all branches of your application, you get the assurance that your code both runs and produces correct results.
EDIT: I should point out that the ability to compare two types, not depend on method names until the last second, etc. are core features of Ruby.
You don't call a method so much as you send a message to an object. The object is then responsible for figuring out how to handle the method. In Rails this is used to access DB columns in ActiveRecord. There are no methods for the columns until a message with the column name is sent to the object.
Static typing in Ruby goes against the duck typing system. One can often get polymorphism for free without worrying about complex inheritance/interface schemes.
I suggest embracing these features and compensate for the uncertainty through testing
Ruby doesn't allow you to redefine the == operator for Object. In ruby 1.8 you can't, Ruby 1.9 was supposed to do but I haven't been able to get my script working for core classes. It works well for custom defined objects.
class Object
alias :equal_without_warning :==
def ==(object)
unless self.class == object.class
warn("Comparing `#{self.class}' with `#{object.class}'")
end
equal_without_warning(object)
end
end
Assuming I didn't do some stupid coding error, the answer is NO: you can't check whether you are comparing different type of objects.
Also, I would say you don't. Actually Ruby isn't designed to work in this way, this is more a java approach rather than Ruby style.
Ruby isn't supposed to be safe. It lets you compare any two objects, and that's where much of its power comes from. Rails wouldn't be possible without such dynamic design.
Even a compiled language such as Java or C won't stop you from doing == on two objects. As Ben said, it's best to test first. Inspect the structures you're working with. One way to get information about a Ruby object is to use:
puts object.class
In general, the best way (I know of) to avoid this type of issue for dynamic/scripting languages is to move "logic" to methods/commands and write unit tests for them. Basically, anything that can fail should be tested. The code on the page should be dumb logic... rather than display only those items that meet a certain criteria, it should display all items, and get that list of items from a method that only returns the ones that should be displayed.
Two things I'd suggest:
One: Read up on IRB (or script/console for rails). A common development practice in dynamic languages is to try out snippets of code inside a "live" interpreter (like IRB or the rails console). This practice goes back to the earliest dynamic languages like Smalltalk and Lisp. Ruby-debug is also really useful for troubleshooting problems and would have been a really easy way to figure out the error in your example.
Two: Read up on "Duck Typing". "Types" and variables work a little bit differently in Ruby than many folks expect them to. As I understand it, a variable like user.id doesn't have a "type". The value pointed to by user.id does have a type, but the variable itself doesn't. I believe that's part of why there's no tool that would have told you what your error was in advance of running the program. Comparing those two variables isn't an error because the variables don't have a type. user.id was pointing to an integer at that point in your program, but it would be perfectly legal to assign user.id to point to a string, at which point that comparison would have made a lot more sense. :-)
The best solution I found was a IDE that did on-the-fly syntax checking, such as RubyMine. I'm not sure if it would have solved my original problem but it has helped me find and fix several other syntax and compile errors. Thank you everyone for your suggestions.