I'm creating models that are specific to another model (which will ultimately be embedded in the parent model using Mongoid). Now I'm just stuck with trying to figure out how to name them. I've seen it done both ways, so I don't know what to do:
Singular:
models/
post.rb
post/
comment.rb
comment/
happy_comment.rb
class Post
class Post::Comment
class Post::Comment::HappyComment < Post::Comment
Plural:
models/
post.rb
posts/
comment.rb
comments/
happy_comment.rb
class Post
class Posts::Comment
class Posts::Comments::HappyComment < Posts::Comment
The benefit to the later is that there can be Posts and Comments modules for wrapping around each child model:
module Posts
module Comments
class HappyComment < Comment
What is the correct way to namespace these child models?
There is no generally accepted convention for this and you can use both, depending on what you find better. From technical point of view, Rails will not behave differently in the two situations.
P.S. Are you going to also have other models, named Post, Comment etc.? If not, than maybe the best approach is to just have each model at the top level of your models/ folder.
Related
I would like to convert all my models in a rails app to use uuid as id and maybe if I need, add some fields that will be common to all my models. To do this I am thinking of, instead of doing this:
class MyModel < ActiveRecord::Base
end
doing this
class CommonUUIDModel < ActiveRecord::Base
some_uuid_related_information
end
class MyModel < CommonUUIDModel
end
my questions are:
How can I achieve this (what should be in the place of some_uuid_related_information and is this a good practice for Rails applications?
Prefer extension (mixing in modules) to inheritance (subclasses).
In other words, make a module that alters the models in a uniform way and include that module in all classes that use it.
This is especially true of ActiveRecord-backed models, since subclassing often signals STI (single table inheritance)
i'm a super newbie in rails and i need to see a sample code on how to implement Single table iheritance, i have a model called Listing as a super class, and i have subclasses LawFirms and Paralegal, these all extend the Listing model, now i need to be able to create a new listing, but when i am creating i need the form to have an option to select either Law Firm or Paralegal, when Law Firm option is selected, it should show a form for creating a LawFirm object which is different from the Paralegal Object because a law firm has advocates and a paralegal wont have advocates.
So far my models look like this
class Listing < ActiveRecord::Base
end
class LawFirm < Listing
has_many :advocates
end
class Paralegal < Listing
end
How do i create the controller? and the form?
I'm not sure that inheritance is the right solution for this. Inheritance is used for an is-a relationship. For example, a Nissan is a car so Nissan would inherit from the car class. You might be better off having LawFrim or Paralegal as objects in a Listing using a nested resource in rails. You could then add some checks in the controller to make sure it only has one or the other of those objects.
I have the following:
a Link model
a LinkItem model, which I want to be of the following type
a comment
a tag
...
I am using this code:
Link model
class Link < ActiveRecord::Base
has_many :link_items
end
LinkItem model
class LinkItem < ActiveRecord::Base
belongs_to :link
end
class Comment < LinkItem
end
class Tag < LinkItem
end
Now I don't know how to tell Rails that my LinkItem model is supposed to be polymorphic. I've read the Rails Guide on asociations and other tutorials, but these just describe how to create a belongs_to association to multiple other models, not the other way around.
So my question would be:
How do I create a has_many association where the associated instances can be of different types? Or would it be better to create seperate models for comments, tags, etc. and just associate each of them individually with my Link model?
EDIT
Actually my code works.
I just tried using a 'type'-column (instead of 'link_item_type') in my database and rails automatically used it to save/determine the correct subclass of my LinkItems (thanks Wizard of Ogz for the hint)
However I still can't access the subclasses of LinkItem without referencing a LinkItem first. Is this some kind of lazyloading?
If you are looking for polymorphic association nicholaides has the right way .
If you are looking for has_meny polymorphic association , check out the answer to "Setting up a polymorphic has_many :through relationship".
This is called a polymorphic association. Here is some documentation.
I just dealt with what I think is the same issue.
My filename for my model was wrong. I initially created it with one name (ex. link_tag.rb), and then changed the name of the class (ex. from LinkTag to Tag) on the fly without changing the name of the file (ex. tag.rb).
When I renamed the file correctly, it worked as expected.
In summary, the name of the file needed to match the name of the class.
I know this post is a little old, but maybe that will help someone someday!
I user polymorphic associations a lot!
I would first watch this RailsCast and then the documentation suggested by nicholaides.
It perfectly explains how to create both sides of the association.
I have a class heirarchy but not single-table inheritence.
ThrowAway < ActiveRecord::Base
and
Junk < ThrowAway
the problem is that all ThrowAway objects have references to a Location. A Location
belongs_to :throw_away, :polymprohic => true
The problem is that if I define
ThrowAway < ActiveRecord::Base
has_many :locations, :as => :throw_away
end
then even if Junk inherits from it and defines a different table name, the throw_away_type column will always be set to ThrowAway where I actually want it set to Junk.
Now there will be many of these subclasses so there will be Stuff < ThrowAway Rags < ThrowAway etc. I want them all to have a Location without defining a location relationship in each individual class.
Is this possible with rails? Problem is that there is not just location, there are other of these sort of relationships and I'd rather follow some DRY here. I'm assuming I need to create a generator method which will execute on the current object and generate these relationships generators on runtime.
Thanks.
ActiveRecord doesn't seem to be able to cooperate with model inheritance that's not STI. Fortunately, that's probably not what you really want anyway. You probably want a mixin instead.
Create a module that contains all of the functionality that you want your models to share in common, and have all of your models include that module. I would probably put the module in your models directory, but give it an adjective as a name. Some folks might put the module in the lib directory or create a lib directory within the models directory for it.
In your case, you'll want the association to be defined at the time the module is mixed in, so you'll need to use a callback. Something like..
module Trashable
def self.included(base)
base.send :has_many, :locations, :as => :throw_away
end
end
Usually there are a lot of models in a Ruby on Rails project, so:
Is it a good practice to namespace them (in modules/folders)? What are the downsides?
EG:
Shop
category.rb
details.rb
Products
category.rb
base.rb
etc
(instead of ShopCategory, to have Shop::Category?)
Should also the controllers be namespaced in the same manner?
I've recently found this post but back from 2007 by Pratik Naik. Says there namespace in models doesn't really resemble databases. Uses something like below. Even there's a quote from DHH too.
Rails::Initializer.run do |config|
# Your existing stuff
config.load_paths << "#{RAILS_ROOT}/app/models/pets"
end
http://m.onkey.org/2007/12/9/namespaced-models
p/s: I don't know whether the post is still relevant or not, just something I found recently when I wanted namespaces in my models.
I'm doing that a lot.
So yes I think that's something you should do.
It'll be be a lot easier for you to view models if you have them subdivided in subdirectories instead of having them all in the same one.
The same recommendation is also valid for your controllers and your views.
I recommend using single table inheritance for your category model. For example:
Category < ActiveRecord::Base end
ShopCategory < Category end
ProductCategory < Category end
Shop < ActiveRecord::Base
belongs_to :shop_category
end
Product < ActiveRecord::Base
belongs_to :product_category
end
This will encapsulate commonly used category behaviour and attributes into a single model and could allow you to reuse a lot of code and have a single controller. Using namespacing only makes sense to me when the underlying classes have some sort of data/functionality in common. (example: acts_as_versioned creates a Version class namespaced under the model)