In my rails application I have an upvote system, it allows people to upvote a pin. Then when a user upvoted a pin I render a list of upvoted pins in the user profile. What I want to do know is to provide a list of the users who upvoted a specific pin.
app/controller/pins_controller.rb
def upvote
#pin = Pin.find(params[:id])
if #pin.votes.create(user_id: current_user.id)
flash[:notice] = "Thank you for upvoting! You can upvote a startup only once."
redirect_to(pins_path)
else
flash[:notice] = "You have already upvoted this!"
redirect_to(pins_path)
end
end
app/controller/users_controller.rb
def show
#user = User.find(params[:id])
#pins_for_user = []
#user.votes.each do |vote|
#pins_for_user << vote.pin
end
end
app/models/pin.rb
class Pin < ActiveRecord::Base
belongs_to :user
has_many :votes, dependent: :destroy
has_many :upvoted_users, through: :votes, source: :user
has_many :rewards, dependent: :destroy
has_many :rewarded_users, through: :rewards, source: :user
has_attached_file :image, :styles => { :medium => "300x300>", :thumb => "100x100>" }
has_attached_file :logo, :styles => { :medium => "300x300>", :thumb => "100x100>" }
end
app/models/user.rb
class User < ActiveRecord::Base
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
has_many :pins
has_many :votes, dependent: :destroy
has_many :upvoted_pins, through: :votes, source: :pin
has_many :rewards, dependent: :destroy
has_many :rewarded_pins, through: :rewards, source: :pin
end
app/models/vote.rb
class Vote < ActiveRecord::Base
belongs_to :user
belongs_to :pin, counter_cache: true
validates_uniqueness_of :pin_id, scope: :user_id
end
I was thinking of using #pin.upvoted_users to provide this list but I didn't succeeded to implement it correctly, any ideas?
Related
All, i am currently learning Rails and proceeding with a project and i am running into an issue.I am unable to show the image of the user who the post belongs to.
When i go to the home page, i should see the post of the users who you are following ... and unfortunately i am not sure how i can show the image of user who the post belongs to.... i can show their post but not sure how i show their image. I must say i am using paperclip gem.
user model
class User < ActiveRecord::Base
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
has_attached_file :avatar, :styles => { :medium => "300x300>", :thumb => "100x100#" }, :default_url => "/images/:style/missing.png"
validates_attachment_content_type :avatar, :content_type => /\Aimage/.*\Z/
has_many :followeds, through: :relationships
has_many :relationships, foreign_key: "follower_id", dependent: :destroy
has_many :followed_users, through: :relationships, source: :followed
has_many :reverse_relationships, foreign_key: "followed_id"
has_many :reverse_relationships, foreign_key: "followed_id",
class_name: "Relationship",
dependent: :destroy
has_many :followers, through: :reverse_relationships, source: :follower
has_many:avatar, dependent: :destroy
has_many :posts, dependent: :destroy # remove a user's posts if his account is deleted.
has_many :active_relationships, class_name: "Relationship", foreign_key: "follower_id", dependent: :destroy
has_many :passive_relationships, class_name: "Relationship", foreign_key: "followed_id", dependent: :destroy
has_many :following, through: :active_relationships, source: :followed
has_many :followers, through: :passive_relationships, source: :follower
def avatar_url
avatar.url(:medium)
end
# helper methods
# follow another user
def follow(other)
active_relationships.create(followed_id: other.id)
end
# unfollow a user
def unfollow(other)
active_relationships.find_by(followed_id: other.id).destroy
end
# is following a user?
def following?(other)
following.include?(other)
end
end
i can get the current user image, but if i log into my account, and i am following someone, i want to see their image not mine for their associated post..
<%=image_tag(current_user.avatar.url, class: "img-circle img-responsive img-raised", :size => "100x100") %>
Your post has to have belongs_to :user and user_id in database, then you can do it like this:
#posts.each do |post|
<%=image_tag(post.user.avatar.url, class: "img-circle img-responsive img-raised", :size => "100x100") %>
end
But i see you have has_many :avatar it could be mistake in you code posted here, if not you have to first select which avatar_url you want to use.
I have set up my scopes and all are working as expected but I could find a way to filter the friends posts in one scope.
In the model
scope :popular, ->{ where("cached_votes_up > '20'") } # change this to a much bigger number overtime
scope :following, ->{ where(Post.current_user.following.ids.include? user_id) }
scope :ordered, -> { order(created_at: :desc) }
In the controller
#post = Post.ordered.popular.following.paginate(:per_page => 10, :page => 1)
How can I add the following/friend filtering for a scope so i can merge them with other scopes.
I'm trying to make the page display posts with more than 20 likes and also display friends' posts even if they're not above 20.
Thanks in advance.
EDIT:
class Post < ActiveRecord::Base
include PublicActivity::Common
cattr_accessor :current_usercontroller.current_user}
scope :popular, ->{ where("cached_votes_up > '1'") } # change this to a much bigger number overtimeuser_id) }
scope :ordered, -> { order(created_at: :desc) }
acts_as_votable
has_attached_file :image, styles: { medium: "550", thumb: "100x100>" }, default_url: "/images/:style/missing.png"
validates_attachment_content_type :image, content_type: /\Aimage\/.*\Z/
belongs_to :user
belongs_to :category
validates :user_id, presence: true
validates :image, presence: true
default_scope { order("created_at DESC")}
has_many :comments
is_impressionable # :counter_cache => true, :column_name => :my_column_name, :unique => true
def previous_post
self.class.where("created_at < ?", created_at).order(created_at: :desc).first
end
def next_post
self.class.where("created_at > ?", created_at).order(created_at: :asc).last
end
end
and relationships.rb
class Relationship < ActiveRecord::Base
belongs_to :follower, class_name: "User"
belongs_to :followed, class_name: "User"
validates :follower_id, presence: true
validates :followed_id, presence: true
end
and the user.rb
class User < ActiveRecord::Base
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
include PublicActivity::Common
acts_as_voter
is_impressionable
has_attached_file :image, :styles => { :medium => "300x300>", :thumb => "100x100#" }, :default_url => "missing.jpg"
has_attached_file :cover, :styles => { :medium => "300x300>", :thumb => "100x100#" }, :default_url => "missing.jpg"
has_many :posts, dependent: :destroy
has_many :active_relationships, class_name: 'Relationship', foreign_key: "follower_id", dependent: :destroy
has_many :passive_relationships, class_name: 'Relationship', foreign_key: "followed_id", dependent: :destroy
has_many :following, through: :active_relationships, source: :followed
has_many :followers, through: :passive_relationships, source: :follower
has_many :comments
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
validates_attachment :image, :cover,
content_type: { content_type: ["image/jpeg", "image/gif", "image/png"] }
def follow(other)
active_relationships.create(followed_id: other.id)
end
def unfollow(other)
active_relationships.find_by(followed_id: other.id).destroy
end
def following?(other)
following.include?(other)
end
end
I have a rails app with a basic set up to allows users to upvote pins, those pins are ordered from the most upvoted to the less upvoted. What I would like to do now is to render the lists of pins that a user upvoted on his profile.
Here is my config:
app/controllers/pins_controllers.rb
def upvote
#pin = Pin.find(params[:id])
if #pin.votes.create(user_id: current_user.id)
flash[:notice] = "Thank you for upvoting! You can upvote a startup only once."
redirect_to(pins_path)
else
flash[:notice] = "You have already upvoted this!"
redirect_to(pins_path)
end
end
app/models/pin.rb
class Pin < ActiveRecord::Base
belongs_to :user
has_many :votes, dependent: :destroy
has_many :upvoted_users, through: :votes, source: :user
has_attached_file :image, :styles => { :medium => "300x300>", :thumb => "100x100>" }
has_attached_file :logo, :styles => { :medium => "300x300>", :thumb => "100x100>" }
end
app/models/user.rb
class User < ActiveRecord::Base
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
has_many :pins
has_many :votes, dependent: :destroy
has_many :upvoted_pins, through: :votes, source: :pin
end
app/models/vote.rb
class Vote < ActiveRecord::Base
belongs_to :user
belongs_to :pin, counter_cache: true
validates_uniqueness_of :pin_id, scope: :user_id
end
And my routes.rb
resources :pins do
member do
post 'upvote'
end
end
Do you have any ideas how I could do that?
You can get the pins a user #user upvoted for example by the following:
#pins_for_user = []
#user.votes.each do |vote|
#pins_for_user << vote.pin
end
You can embedd this in your user controller, for example in the show method.
Then you can refer to #pins_for_user in your show view (show.html.erb) and display it by:
<% #pins_for_user.each do |pin| %>
<%= pin.name %> # or any other code to display that special pin
<% end %>
My brain is getting tangled. I have users and they can have one plan and one subscription. I am using ryan bates example for subscription and have everything working except I don't know how to get the user_id into the subscription
here is my subscription controller.
class SubscriptionsController < ApplicationController
before_action :authenticate_user!
def new
plan = Plan.find(params[:plan_id])
#subscription = plan.subscriptions.build
end
def create
#subscription = Subscription.new(subscription_params)
if #subscription.save
redirect_to #subscription, :notice => "Thank you for subscribing!"
else
render :new
end
end
def show
#subscription = Subscription.find(params[:id])
end
private
def subscription_params
params.require(:subscription).permit(:plan_id, :email, :user_id)
end
end
here is my user model
class User < ActiveRecord::Base
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable, :confirmable
has_many :videos
has_many :votes
has_many :favorites
has_many :videos_with_votes, :through => :votes, :source => :video
has_many :videos_with_favorites, :through => :favorites, :source => :video
has_one :subscription
has_one :plan, :through => :subscription
has_attached_file :avatar, :styles => { :medium => "300x300#", :thumb => "80x80#" }
def voted?(video)
votes.exists?(video_id: video.id)
end
def favorited?(video)
favorites.exists?(video_id: video.id)
end
end
here is my plan model
class Plan < ActiveRecord::Base
has_many :subscriptions
has_many :users
end
here is my subscription model
class Subscription < ActiveRecord::Base
belongs_to :plan
belongs_to :user
validates_presence_of :plan_id
validates_presence_of :email
end
I have a Post model:
class Post < ActiveRecord::Base
attr_accessible :title, :content, :tag_names
belongs_to :user
has_many :taggings, :dependent => :destroy
has_many :tags, :through => :taggings
attr_writer :tag_names
after_save :assign_tags
def tag_names
#tag_names || tags.map(&:name).join(' ')
end
private
def assign_tags
if #tag_names
self.tags = #tag_names.split(" ").map do |name|
Tag.find_or_create_by_name(name)
end
end
end
end
a Tag model:
class Tag < ActiveRecord::Base
has_many :taggings, :dependent => :destroy
has_many :posts, :through => :taggings
has_many :subscriptions
has_many :subscribed_users, :source => :user, :through => :subscriptions
end
and an User model:
class User < ActiveRecord::Base
# Include default devise modules. Others available are:
# :token_authenticatable, :encryptable, :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable,
:omniauthable
# Setup accessible (or protected) attributes for your model
attr_accessible :email, :password, :password_confirmation, :remember_me, :username, :avatar
has_many :posts, :dependent => :destroy
has_many :subscriptions
has_many :subscribed_tags, :source => :tag, :through => :subscriptions
end
posts and tags have a many-to-many relationship (the following is the model for the join table):
class Tagging < ActiveRecord::Base
belongs_to :post
belongs_to :tag
end
users and tags have also a many-to-many relationship:
class Subscription < ActiveRecord::Base
belongs_to :user
belongs_to :tag
end
Only posts with tags that the user has subscribed to should display:
def index
#title = "Posts"
#posts = current_user.subscribed_tags.map(&:posts).flatten.paginate(:page => params[:page], :per_page => 5)
Let say I create a tag for a post:
$ post.tags.create(:name => "food")
$ post.tags
=> [#<Tag id: 6, name: "food", created_at: "2012-03-02 10:03:59", updated_at: "2012-03-02 10:03:59"]
Now I have no idea how to subscribe the user to that tag.
I tried this:
$ user.subscribed_tags.create(:name => "food")
$ post.tags
=> [#<Tag id: 7, name: "food", created_at: "2012-03-02 10:04:38", updated_at: "2012-03-02 10:04:38"]
But as you can see it actually creates a new tag instead of adding the food tag with ID 6 to the user.subscribed_tags attribute.
Any suggestions to solve this issue?
You can append to the user's subscriped_tags, as you would do an array.
ex: user.subscribed_tags << Tag.find_by_name("food")