I've Googled and searched the forums but can't seem to find an answer that fits my scenario.
Let's say have the following models:
class TextProblem < ActiveRecord::Base
belongs_to :askable, :polymorphic => true
...
end
class MultipleChoice < ActiveRecord::Base
belongs_to :askable, :polymorphic => true
...
end
class WordMatch < ActiveRecord::Base
belongs_to :askable, :polymorphic => true
...
end
Now I have another model called question. It has a field named question_type_id that indicates what type of question it is and a field named question_id that is the foreign key to one of the askables.. I want to do something like this:
class Question < ActiveRecord::Base
has_one :askable, :foreign_key => 'question_id' ....
end
and give it the correct askable but I'm not sure how to write the association. Am I looking at this right or should I be trying to achieve this another way?
Any help is appreciated!
You should have your association the other way round
class Question < ActiveRecord::Base
belongs_to :askable, :polymorphic => true
end
class TextProblem < ActiveRecord::Base
has_many :questions, :as => :askable
...
end
class MultipleChoice < ActiveRecord::Base
has_many :questions, :as => :askable
...
end
class WordMatch < ActiveRecord::Base
has_many :questions, :as => :askable
...
end
Refer to this.
Related
I have a fairly normal class structure, using a polymorphic association:
class Contact < ActiveRecord::Base
has_many :opportunities, :as => :has_opportunities, dependent: :destroy
end
class Company < ActiveRecord::Base
has_many :opportunities, :as => :has_opportunities, dependent: :destroy
end
class Opportunity < ActiveRecord::Base
belongs_to :has_opportunities, polymorphic: true
belongs_to :contact, foreign_key: 'has_opportunities_id', conditions: "opportunities.has_opportunities_type = 'Contact'"
belongs_to :company, foreign_key: 'has_opportunities_id', conditions: "opportunities.has_opportunities_type = 'Company'"
end
In Rails 4 using :conditions has been deprecated, but I can't figure out the "new" syntax required to allow access to the parent object from the child.
Edit: Yes, you can do opportunity.has_opportunities which will return you a Contact or a Company, but it is often "nicer" in code to use opportunity.contact or opportunity.company
Can't you simply set it up as a regular polymorphic association?
class Opportunity < ActiveRecord::Base
belongs_to :has_opportunities, polymorphic: true
end
Here are my relevant models:
class ListItem < ActiveRecord::Base
belongs_to :inventory_item
belongs_to :shopping_list
belongs_to :item
end
class ShoppingList < ActiveRecord::Base
has_many :list_items
belongs_to :user, :foreign_key => :user_id
end
class InventoryItem < ActiveRecord::Base
belongs_to :item, :foreign_key => :item_id
belongs_to :vendor
has_many :list_items
end
I'm trying to access attributes of InventoryItem in my view. Here's what I currently have in my ShoppingListController.
def show
#list_items = ShoppingList.find(params[:id]).list_items
end
Can I do something like #inventory_items = #list_items.inventory_items? That code and variants of it that I've tried haven't worked. What am i missing here? Any tips for accessing attributes through multiple models like this? Thanks in advance!
The most straight forward approach would be to use has_many through on the ShoppingList class:
has_many :inventory_items, through: :list_items
I have a tags model that I'd like to be polymorphic, but I don't want five records for a tag of "video" for example, I want to create the tag once and be able to use it on a variety of models. I've ready some of the questions here about doing that, but I'm not quite getting how to make it work.
So I've got:
class Tag < ActiveRecord::Base
belongs_to :tagable, :polymorphic => true
end
and
class Post < ActiveRecord::Base
has_many :tags, :through => :tag_assignments
end
and
class TagAssignment < ActiveRecord::Base
has_many :tags, :as => :taggable
end
Seems to me that should work, but... reading all the questions here I know I need a :source => option in there somewhere to tie it all together, but I'm just not following exactly how to do it. Can anyone help?
You have to redo your models as follows:
class Tag < ActiveRecord::Base
has_many :tag_assignments
end
class TagAssignment < ActiveRecord::Base
belongs_to :tagable, :polymorphic => true
belongs_to :tag
end
class Post < ActiveRecord::Base
has_many :tag_assignments, :as => :tagable
has_many :tags, :through => :tag_assignments
end
Now given a post you can get its tags as follows:
post.tags
Note
You should consider using the acts-as-taggable-on gem for your use case.
Models:
class Thread < ActiveRecord::Base
has_many :threaded, :through => :threaded, :foreign_key => :thread_id
class ThreadFeed < ActiveRecord::Base
belongs_to :threaded, :polymorphic => true
Model Fields
Thread (id)
ThreadFeed (id, thread_id, threaded_id, threaded_type)
Problem is with:
#thread.threaded
Rails is using (threaded_id, threaded_type) as the foreign key and I want thread_id to be the foreign key.
Take a look into this Railscast, Polymorphism
It will give you a better insight into how Polymorphism works.
First issue I notice is that it should be through :threadfeed, not :threaded
class Thread < ActiveRecord::Base
has_many :threadfeeds, :as => :threaded
In the Railscast, he has:
class Comment < ActiveRecord::Base
belongs_to :commentable, :polymorphic => true
end
class Article < ActiveRecord::Base
has_many :comments, :as => :commentable
end
class Photo < ActiveRecord::Base
has_many :comments, :as => :commentable
#...
end
class Event < ActiveRecord::Base
has_many :comments, :as => :commentable
end
The first problem is that Thread doesn't know what feed is:
class Thread < ActiveRecord::Base
has_many :feeds, :through => :thread_feeds, :as => :feeded
has_many :thread_feeds
class ThreadFeed < ActiveRecord::Base
belongs_to :feeded, :polymorphic => true
The second problem is the complexity of polymorphic. Here's a great article on it: http://blog.hasmanythrough.com/2006/4/3/polymorphic-through
Right now I have a rich many-to-many association with VideoVote as the independent record.
class VideoVote < ActiveRecord::Base
belongs_to :user
belongs_to :video
end
class User < ActiveRecord::Base
has_many :video_votes
has_many :voted_videos,
:through => :video_votes,
:source => :video
end
class Video < ActiveRecord::Base
has_many :video_votes
has_many :voted_users,
:through => :video_votes,
:source => :user
end
However, I want to trasform this into a polymorphic association where comments can also have many VideoVotes (I realize this is confusing, so I should probably change it to Votes). (also, a video will have many comments.) How should I do this?
You first want to add voteable_id:integer and voteable_type:string to your video_votes table.
Then your models will look like:
class VideoVote < ActiveRecord::Base
belongs_to :voteable, :polymorphic => true
end
class Comment < ActiveRecord::Base
has_many :video_votes, :as => :voteable
#code
end
class Video < ActiveRecord::Base
has_many :video_votes, :as => :voteable
#code
end
Then you can access them just like any other has_many:
#video.video_votes
#comment.video_votes
#etc.