Having set up my polymorphic relationship like so:
class Review < ActiveRecord::Base
belongs_to :reviewable, :polymorphic => true
belongs_to :user
end
class Wine < ActiveRecord::Base
has_many :reviews, :as => :reviewable
end
class Beer < ActiveRecord::Base
has_many :reviews, :as => :reviewable
end
I can do Wine.last.reviews and Beer.find(3).reviews etc...
What I'm strugling to do is go in the other direction, i.e. Lets say I want to find the last 10 reviews for Wine and the last 10 reviews for Beer.
The easiest way to do this is probably to add a named scope to your Review model that specifies the reviewable_type column.
Like so:
class Review < ActiveRecord::Base
belongs_to :reviewable, :polymorphic => true
belongs_to :user
named_scope :for_wines, :conditions => { :reviewable_type => 'Wine' }
named_scope :for_beers, :conditions => { :reviewable_type => 'Beer' }
end
That way you have the flexibility of scoping when finding your results...
Review.for_wines.approved.all
Review.for_beers.active.find(:all, :order => 'created_at')
etc
Related
I have 3 tables Collections, Tracks and ProductContributors
Association of them is as follows
class Collection < ActiveRecord::Base
has_many :product_contributors, :as => :product
has_many :tracks, :through => Product_contributors, :as=> :product
end
class Track < ActiveRecord::Base
has_many :product_contributors, :as => :product
has_many :collections, :through => Product_contributors, :as => :product
end
class ProductContributor < < ActiveRecord::Base
belongs_to :product, :polymorphic => true
belongs_to :collection
belongs_to :track
end
whenever i hit the url for product contributor i get the following error :
Expected /app/models/track.rb to define TRACK
I've gone through this url but didnt help me in any case. I dont have the autoload issue, all my models are loaded properl
Any help would be highly appreciated..!!
I dare say its because of the typo in your Track class.
has_many :collections, :through => Product_contributors, :as => :product
is not valid. Try:
has_many :collections, :through => :product_contributors, :as => :product
Basically, it is trying to load the Model, but its finding the typo in the association, and it is then not loading, causing it to seem like the class is not there. I assume you will have a similar situation with the Collection class as well.
From a person record I need to be able to add/display documents of specific types. Including the conditions for category_id works but at this point I can not assume that the category ids will remain the same as development progresses. This is also an issue with testing where I only create the categories I need.
Is there a way I can dynamically set the category_id, for example something like this:
has_many :personal_documents, :as => :documentable, :conditions => "category_id = #{DocumentCategory.find_by_name('Personal').id}", class_name: 'Document'
Models:
Person < AR::Base
has_many :documents, :as => :documentable
has_many :personal_documents, :as => :documentable, #:conditions => "category_id = 1"
has_many :legal_documents, :as => :documentable, #:conditions => "category_id = 2"
end
Animal < AR::Base
has_many :documents, :as => :documentable
end
Document < AR::Base
belongs_to :person
belongs_to :category
end
Could you simply use seeds with static ids?
I have these models (psuedocode):
class Order
has_many :line_items
end
class LineItem
belongs_to :purchasable, :polymorphic => true
belongs_to :order
end
class Tile
has_one :line_item, :as => :purchasable
end
I want to make a scope that allows me to access tiles from an order. something like Order#tiles so that I can do things like this in controllers:
my_order.tiles.new(...)
my_order.tiles.find(params[:id]).update_attributes(...)
How can I construct such a scope? (or is there another technique I should use?)
The associations you have don't work together. I think you might be looking for something like this:
class Order
has_many :line_items
has_many :tiles, :through => :line_items, :source => :purchasable, :source_type => "Tile"
...
end
class LineItem
belongs_to :order
belongs_to :purchasable, :polymorphic => true
...
end
class Tile
has_many :line_items, :as => :purchasable
...
end
I'm using has_many_polymorphs to create a "Favorites" feature on a site where multiple users can post stories and make comments. I want users to be able to "favorite" stories and comments.
class User < ActiveRecord::Base
has_many :stories
has_many :comments
has_many_polymorphs :favorites, :from => [:stories, :comments]
end
class Story < ActiveRecord::Base
belongs_to :user, :counter_cache => true
has_many :comments
end
class Comment < ActiveRecord::Base
belongs_to :user, :counter_cache => true
belongs_to :story, :counter_cache => true
end
class FavoritesUser < ActiveRecord::Base
belongs_to :user
belongs_to :favorite, :polymorphic => true
end
Now say #user writes a story. Now #user.stories.size = 1. Then #user favorites a different story. Now #user.stories... wait a minute. #user has_many :stories and :has_many :stories through :favorites.
The issue arises when I attempt to call #user.stories or #user.comments. I want to call #user.stories for stories they own and #user.favorites.stories for stories they favorite.
So I tried this:
class User < ActiveRecord::Base
has_many :stories
has_many :comments
has_many_polymorphs :favorites, :from => [:favorite_stories, :favorite_comments]
end
and then subclassed Story and Comment like so:
class FavoriteStory < Story
end
class FavoriteComment < Comment
end
That fixed the problem because now I can call #user.stories and #user.favorite_stories.
BUT when I get this error in reference to comments:
ActiveRecord::Associations::PolymorphicError in UsersController#show
Could not find a valid class for :favorite_comments (tried FavoriteComment). If it's namespaced, be sure to specify it as :"module/favorite_comments" instead.
I found discussion of this error in a similar context, but it doesn't answer my question.
What's going on here? How can I do this better?
What about something like this?
class UserFavorite < ActiveRecord::Base
belongs_to :user
belongs_to :favorite, :polymorphic => true
end
class User < ActiveRecord::Base
has_many :favourite_story_items, :class_name => "UserFavourite", :conditions => "type = 'Story'"
has_many :favourite_stories, :through => :favourite_story_items, :as => :favourite
has_many :favourite_comment_items, :class_name => "UserFavourite", :conditions => "type = 'Comment'"
has_many :favourite_comments, :through => :favourite_comment_items, :as => :favourite
end
I have an app with country preferences. A user will have 2 types of country preferences - event and research. In the future there may be more. I was leaning more towards having 2 tables to represent this over using STI. I'm having a bit of trouble configuring Rails elegantly to do this. I could hack it but I would rather do this by Rails convention. What I want is something like this:
class User < ActiveRecord::Base
has_many event_countries, :through => :event_countries, :class_name => 'Country'
has_many research_countries, :through => :research_countries, :class_name => 'Country'
end
class EventCountry < ActiveRecord::Base
belongs_to :country
belongs_to :user
end
class ResearchCountry < ActiveRecord::Base
belongs_to :country
belongs_to :user
end
class Country < ActiveRecord::Base
...
end
This doesn't work though. Given this "pseudo code" does anyone know how to actually implement this in Rails?
I think you're going about declaring them wrong, because this should work properly. That's what the :through directive is for:
class User < ActiveRecord::Base
has_many :event_countries
has_many :countries_with_events,
:through => :event_countries,
:source => :country
has_many :research_countries
has_many :countries_with_researches,
:through => :research_countries,
:source => :country
end
class EventCountry < ActiveRecord::Base
belongs_to :country
belongs_to :user
end
class ResearchCountry < ActiveRecord::Base
belongs_to :country
belongs_to :user
end
class Country < ActiveRecord::Base
# ...
end
A lot of the awkwardness comes from the labels you've chosen for the tables. Although they'd seem reasonable at first glance, the way you use them ends up making them difficult.
You might want to call research_countries something like user_research_countries so that the relationship name can be user.research_countries as the :through:
class User < ActiveRecord::Base
has_many :user_event_countries
has_many :event_countries,
:through => :user_event_countries,
:source => :country
has_many :user_research_countries
has_many :research_countries,
:through => :user_research_countries,
:source => :country
end
class UserEventCountry < ActiveRecord::Base
belongs_to :country
belongs_to :user
end
class UserResearchCountry < ActiveRecord::Base
belongs_to :country
belongs_to :user
end
class Country < ActiveRecord::Base
# ...
end
You can refactor this even further by adding a field to the user-country association table that includes one or more flags, which in this case would be research or event or whatever you require later:
class User < ActiveRecord::Base
has_many :user_countries
has_many :event_countries,
:through => :user_countries,
:source => :country,
:conditions => { :event => true }
has_many :research_countries,
:through => :user_countries,
:source => :country,
:conditions => { :research => true }
end
class UserCountry < ActiveRecord::Base
belongs_to :country
belongs_to :user
# * column :event, :boolean
# * column :research, :boolean
end
class Country < ActiveRecord::Base
# ...
end