I have created a feed_item using this migration
class CreateFeeds < ActiveRecord::Migration
def change
create_table :feeds do |t|
t.integer :item_id
t.string :item_type
t.integer :user_id
t.timestamps
end
end
end
class Feed < ActiveRecord::Base
belongs_to :user
belongs_to :item, polymorphic: true
end
and I am displaying the content of the feed like
photos = image_tag feed.item.image_url
post = feed.item.text
I trying to add a vote button so the migration for the vote model looks like
class CreateVotes < ActiveRecord::Migration
def change
create_table :votes do |t|
t.integer :votable_id
t.string :votable_type
t.timestamps
end
end
end
class Vote < ActiveRecord::Base
belongs_to :votable, polymorphic: true
end
class Post < ActiveRecord::Base
belongs_to :user
has_many :votes, as: :votable
end
How do I create the vote controller's create action?
I tried
class VotesController < ApplicationController
def create
@votable = find_votable
@vote = @votable.votes.build(params[:vote])
end
private
def find_votable
params.each do |name, value|
if name =~ /(.+)_id$/
return $1.classify.constantize.find(value)
end
end
nil
end
def vote_params
params.require(:vote).permit(:votable)
end
end
and got undefined metheod "votes"
also tried
@vote = params[:votable_type].classify.constantize.find(params[:votable_type])
I got undefined metheod "classify"
You wouldn't use a VotesController, you would create votes via other models which have a polymorphic relationship with them. In your example above, you would create them via:
post.votes
(assuming post
was an instance of Post
)
The idea behind polymorphic relationships is a many-to-many relationship with multiple models, so you should be creating any 'votable' records via the source models, in this example, Post
.
For instance, you could create a vote
method in your PostController
that would create the vote association as I've outlined above and then add the appropriate route to submit your voting form.
Additionally, your Vote
model could also contain other data, depending on how you want to use voting. For instance, if you wanted to track the number of votes a model gets, you could add a count
column. In which case, you would create the record as:
post.votes.count += 1