Adding friends in ruby on rails - ruby-on-rails

i am following this post for adding users as friends in ruby on rails
http://asciicasts.com/episodes/163-self-referential-association
I am able to add users as friends via rails console but not via the actual page...this is my controller code
class FriendshipsController < ApplicationController
def new
end
def create
#friendship = current_user.friendships.build(:friend_id => params[:friend_id])
if #friendship.save
flash[:notice] = "Added friend."
redirect_to phones_index_path
else
flash[:notice] = "Unable to add friend."
redirect_to phones_index_path
end
end
def show
end
end
Model:
User:
class User < ActiveRecord::Base
# Include default devise modules. Others available are:
# :token_authenticatable, :confirmable,
# :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
has_many :contacts
has_many :phones
has_many :friendships
has_many :friends, :through => :friendships
has_many :inverse_friendships, :class_name => "Friendship", :foreign_key => "friend_id"
has_many :inverse_friends, :through => :inverse_friendships, :source => :user
# Setup accessible (or protected) attributes for your model
attr_accessible :email, :password, :password_confirmation, :remember_me, :user_id
# attr_accessible :title, :body
end
friends:
class Friendship < ActiveRecord::Base
attr_accessible :friend_id, :user_id
belongs_to :user
belongs_to :friend, :class_name => 'User'
end
view:
<h1>Phones#index</h1>
<center>Users in the system<center><br/>
<p><% #phones.each do |variable|%>
<% if #phn.email!= variable.email %>
<br/><%= variable.email %> <%= link_to 'Add as Friend' , friendships_path(:friend_id => #user), :method => :post %>
<%end%>
<%end%>
<p>friends</p>
<% for user in current_user.friends %>
<p><%= user.email %></p>
<%end%>
my view is working correctly .. if i add friends via console and commit it, it displays in the view..
where did i go wrong here??

I was able to correct it..had wrong code in my view file.. thanks a lot jvnill....had it not been for you, I would not have checked my view file... :)
changing friendships_path(:friend_id => #user)
to friendships_path(:friend_id => variable) did the trick

Related

Rails URL for index action includes weird wording for ActiveRecord_Associations

I've published a sizable update to my heroku staging site and besides some saving issues (which I'll post in a separate question), I've noticed some weird things happening to my index url.
Projects are nested under users like such:
routes.rb
resources :users do
resources :projects do
get "cancel", :on => :member
post "cancel" => 'projects#cancel_save', :on => :member
get "rate_supplier", :on => :member
post "rate_supplier" => 'projects#rate_suppliers', :on => :member
end
end
Originally when I viewed a users projects it displayed correctly as
/users/2/projects
But now for some reason the url looks as follows:
users/2/projects.%23<Project::ActiveRecord_Associations_CollectionProxy:0x007fe577ab9820>
I'm not sure why the rest of that stuff is in the url?? And can't find anything online. Help!
UPDATE
The models looks as follows:
project.rb
class Project < ApplicationRecord
belongs_to :user, inverse_of: :projects
belongs_to :budget
belongs_to :industry
belongs_to :project_source
belongs_to :project_status
belongs_to :project_type, class_name: 'Project_type'
has_and_belongs_to_many :features, join_table: :projects_features
has_and_belongs_to_many :addons, join_table: :projects_addons
has_one :project_close_reason
accepts_nested_attributes_for :project_close_reason
has_one :supplier_rating
accepts_nested_attributes_for :supplier_rating
scope :open, -> {
where("project_status_id <=?", 8)
}
scope :closed, -> {
where("project_status_id >?", 8)
}
scope :cancelled, -> {
where("project_status_id =?", 10)
}
scope :completed, -> {
where("project_status_id =?", 9)
}
end
user.rb
class User < ApplicationRecord
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable
validates :password, :presence => true,
:on => :create,
:format => {:with => /\A.*(?=.{8,})(?=.*\d)(?=.*[\#\#\$\%\^\&\+\=]).*\Z/ }
validates :email, :presence => true, :uniqueness => true
has_many :projects, inverse_of: :user
has_many :businesses, inverse_of: :user
accepts_nested_attributes_for :projects
def full_name
"#{last_name}, #{first_name}"
end
end
And here is the link:
<li class="<%= 'active' if params[:controller] == 'projects' %>">
<%= link_to user_projects_path(current_user, #projects) do %>
<i class="fa fa-list" aria-hidden="true"></i> Projects
<% end %>
</li>
And here is the index action in the projects controller
def index
#title = "Your Projects"
#projects = current_user.projects
end
The problem is link_to user_projects_path(current_user, #projects)
I'm figuring you're trying to render the index of projects for a single user.
You don't need to pass #projects in this case. You can simply remove the second argument.
The route you're trying to hit is /users/:user_id/projects.
Since this route only has one parameter (:user_id), you only need to pass one argument to link_to.
To link to individual project show pages, you can do this:
<% #projects.each do |project| %>
<%= link_to user_project_path(current_user, #projects) %>
<% end %>
Note the difference between user_projects_path, which takes only one argument, and user_project_path, which takes two.

Rails: list of pins that a user upvoted

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 %>

Subscription, Plan, User Association

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

Trying to post a user's email address to a membership table in rails

https://github.com/jtrinker/highlands
I'm building an app that allows a user to sign in and join a group. When they click on a group and then click 'join' I would like the user's email address to be posted to the memberships table and the users that have joined that group be saved.
I have a User, Group, and Membership model. Things got a little hairy once I added the membership table.
Models:
class Membership < ActiveRecord::Base
belongs_to :user
belongs_to :group
attr_accessible :user_email
end
class User < ActiveRecord::Base
belongs_to :group
# Include default devise modules. Others available are:
# :token_authenticatable, :confirmable,
# :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
# Setup accessible (or protected) attributes for your model
attr_accessible :email, :username, :password, :password_confirmation, :remember_me
end
class Group < ActiveRecord::Base
has_many :memberships
has_many :users, :through => :memberships
attr_accessible :description, :location, :name
end
groups#show:
<h1><%= #group.name %></h1>
<h4><%= #group.location %></h4>
<p><%= #group.description %></p>
<%= link_to "Join +", memberships_path(:user_email => user.email), :method => :post %>
I'm not sure what I need to do to have a user become a member of a group.
All my code is up on github - https://github.com/jtrinker/highlands
Thanks!
As I see you are sending :post request to groups#create action via link_to, but you can do this another way:
create :join action in Membership controller
def join
# some code here
end
add to route following code
resources :membership do
get :join, via: :get
end
it show return route like:
membership_join GET /membership/:membership_id/join(.:format) membership#join
than in view link to join action with membership_id
<%= link_to "Join +", membership_join_path(:membership_id => #group.id) %>

How to 'subscribe' an user to an existing instance of this Tag model instead of creating a new one?

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")

Resources