Acts_as_follower display follows RoR - ruby-on-rails

I am using a ruby gem called acts_as_follower
My code:
user.rb
class User < ApplicationRecord
acts_as_followable
acts_as_follower
end
users_controller.rb
def follow
#user = User.find(params[:id])
current_user.follow(#user)
redirect_to root_path
end
def unfollow
#user = User.find(params[:id])
current_user.stop_following(#user)
redirect_to root_path
end
followers.html.erb
<% #user.followers.each do |user| %>
<div class="panel panel-default col-md-offset-3 col-md-6">
<br>
<div class="panel panel-heading">
<%= avatar_for(user, size: 50) %>
<h1> <%=link_to user.name, user %></h1>
</div>
</div>
routes.rb
#followers
resources :users do
member do
get :follow
get :unfollow
end
end
How to display the users I follow?

How to display the users I follow?
I believe the method you want is all_following
user.all_following
Returns an array of every followed object for the user, this can be a
collection of different object types, eg: User, Book
So, the below should work
#user.all_following

Related

Rails Error: ActiveRecord::RecordNotFound

I am working on my first Rails project and I am running into a persistent issue. I suspect it has something to do with the routing, however, I can't seem to find anything about it online.
I assume it a rather simple fix, so please take a look and let me know if you can help.
TL;DR
What I was trying to achieve
Account detail Cards display Name, Phone number, and a note.
A delete and edit button would allow users to delete or edit.
What is happening:
Edit and Delete buttons return a weird param.
see image
Image of error, Showing Rails getting a different ID
Controller
class AccountdetailsController < ApplicationController
def index
#accountdetail = Accountdetail.all
end
#I can't find the ID to show the relevent card.
def show
#accountdetail = Accountdetail.find(params[:id])
if #accountdetail.nil?
redirect_to accountdetail_path
end
end
def new
#accountdetail = Accountdetail.new
end
def edit
#accountdetail = Accountdetail.find(params[:id])
end
def create
#accountdetail = Accountdetail.new(accountdetail_params)
if #accountdetail.save
redirect_to #accountdetail
else
render 'new'
end
end
#it affects this
def update
#accountdetail = Accountdetail.find(params[:id])
if #accountdetail.update(accountdetail_params)
redirect_to accountdetail
else
render 'edit'
end
end
#and this
def destroy
#accountdetail = Accountdetail.find(params[:id])
#accountdetail.destroy
redirect_to accountdetail_path
end
private def accountdetail_params
params.require(:accountdetail).permit(:first_name, :last_name, :phone, :notes, :id)
end
end
Index.HTML.ERB
<div class="ui card">
<div class="content">
<a class="header"><%= account.first_name %> <%= account.last_name %> </a>
<div class="meta">
<span class="date"><%= account.phone %></span>
<strong><p><%= account.notes %></p></strong> <br>
<%= link_to "edit", edit_accountdetail_path(#accountdetail) %>
<%= link_to 'Inspect', accountdetail_path(#accountdetail) %>
</div>
</div>
</div>
<% end %>
Routes
Rails.application.routes.draw do
get 'welcome/index'
resources :articles do
resources :comments
end
resources :accountdetails
root 'welcome#index'
end
In you index.html.erb replace following
<%= link_to "edit", edit_accountdetail_path(#accountdetail) %>
<%= link_to 'Inspect', accountdetail_path(#accountdetail) %>
with
<%= link_to "edit", edit_accountdetail_path(account) %>
<%= link_to 'Inspect', accountdetail_path(account) %>
#accountdetail was providing you all the records of account, as it was firing select query in controller. But here we need only one instance, so account.
Hope this helps.

undefined method `to_key' for #<User::ActiveRecord_Relation:0x007f1bf8c2fd60>

I am really new at rails so please forgive me if i can't see it.
I am trying to edit the permissions on each individual user and i am getting this error in form_for:
undefined method `to_key' for #<User::ActiveRecord_Relation:0x007f1bf8c2fd60>
From what i have seen on other questions on stackoverflow, this usually happens when you try to call a collection in a form but this is not the case?
view:
<div class="n-container">
<tr-form data-riot riot-tag="tr-form">
<%= form_for(#user) do |f| %>
<section>
<div class="w-container">
<h1>User permissions</h1>
<% #permissions.each do |permission| %>
<%= check_box_tag 'permission_ids[]', permission.id %>
<div>
<%= permission.description %>
</div>
<% end %>
</div>
</section>
<section>
<div class="f-controls align-right">
<%= f.submit class: "btn fill blue", value: "Submit" %>
</div>
</section>
<% end %>
</tr-form>
</div>
users_controller:
class UsersController < ApplicationController
def user_params
params.require('user').permit(
permissions: []
)
end
def permissions
#user = User.where(id: params[:user_id])
#permissions = Permission.all
end
end
routes:
resources :users do
get 'permissions'
post 'permissions'
end
Thank you in advance!
One should use ActiveRecord::FinderMethods#find, not where, to receive a single instance:
def permissions
# WRONG: where returns a relation
# #user = User.where(id: params[:user_id])
#user = User.find(params[:user_id])
#permissions = Permission.all
end
It worth to mention, that find raise a RecordNotFound exception on fail, hence you probably want to rescue from it:
def permissions
#user = User.find(params[:user_id])
#permissions = Permission.all
rescue RecordNotFound => rnf
# Log or just skip
end
where might be [ab]used here as well, but in such a case you need to explicitly say that you need the only user:
#user = User.where(id: params[:user_id]).first

Subscription form with Stripe not passing parameters properly

I am getting the following error on my Rails 4.2 application. I'm trying to setup subscriptions with Stripe. A subscription belongs to a business and has_one plan.
On my view I pass the params in the URL:
http://localhost:3000/subscriptions/new?plan_id=2&business_id=1001
After I submit the form I get the error below and my code follows. Forgive me if this is a beginner question.
Subscriptions Controller
class SubscriptionsController < ApplicationController
before_action :set_subscription, only: [:show, :edit, :update, :destroy]
# GET /subscriptions
def index
#subscriptions = Subscription.all
end
# GET /subscriptions/1
def show
end
# GET /subscriptions/new
def new
#subscription = Subscription.new
#plan = Plan.find_by id: params["plan_id"]
#business = Business.find_by id: params["business_id"]
end
# POST /subscriptions
def create
#subscription = Subscription.new subscription_params.merge(email: stripe_params["stripeEmail"],
card_token: stripe_params["stripeToken"])
raise "Please, check subscription errors" unless #subscription.valid?
#subscription.process_payment
#subscription.save
redirect_to #subscription, notice: 'Subscription was successfully created.'
rescue => e
flash[:error] = e.message
render :new
end
private
def stripe_params
params.permit :stripeEmail, :stripeToken
end
# Use callbacks to share common setup or constraints between actions.
def set_subscription
#subscription = Subscription.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def subscription_params
params.require(:subscription).permit(:plan_id, :business_id)
end
end
Subscription Model
class Subscription < ActiveRecord::Base
belongs_to :business
has_one :plan
def process_payment
customer = Stripe::Customer.create email: email,
card: card_token
Stripe::Charge.create customer: customer.id,
amount: plan.price * 100,
description: plan.name,
currency: 'usd'
end
end
Subscription View (new.html.erb)
<%= form_for #subscription do |f| %>
<% if #subscription.errors.any? %>
<div id="error_explanation">
<h2>
<%= pluralize(#subscription.errors.count, "error") %>
prohibited this subscription from being saved:
</h2>
<ul>
<% #subscription.errors.full_messages.each do |message| %>
<li>
<%= message %>
</li>
<% end %>
</ul>
</div>
<% end %>
<h1><%= #business.name %></h1>
<div class="field">
<%= f.hidden_field :plan_id, value: #plan.id %>
</div>
<div class="field">
<%= f.hidden_field :business_id, value: #business.id %>
</div>
<div class="actions">
<script
src="https://checkout.stripe.com/checkout.js" class="stripe-button"
data-key="<%= Rails.application.secrets.stripe_publishable_key %>"
data-image="/img/documentation/checkout/marketplace.png"
data-name="Business Name"
data-description="<%= #plan.name %>"
data-amount="<%= #plan.price*100 %>">
</script>
</div>
<% end %>
Plan Model
class Plan < ActiveRecord::Base
belongs_to :subscription
end
Calling render only loads the view for an action, it doesn't run any of the logic in the method behind the action, which is why there is no #plan available when you render :new from the create action.
I figured out the issue was with my association between Plans and Subscriptions. I had Plans belongs_to Subscription when I should have had it the other way around.
class Subscription < ActiveRecord::Base
belongs_to :business
belongs_to :plan
...

Rails - How to route for users with permalink?

For my rails application, I am trying to create a random permalink for my users so that it is not localhost:3000/users/:id, but rather, it is localhost:3000/users/permalink.
I have followed the post made here:
how to make ID a random 8 digit alphanumeric in rails?
Following the post, I have been able to create the random permalink column and pages for my users, but have not been able to get the sub-pages to work. For my users, I currently have sub-pages: Followers, etc.
Question: The pages are currently routed to localhost:3000/users/:id/followers, etc. But does somebody know how to fix routes.rb so that I can also route these pages to localhost:3000/users/permalink/followers, etc.
routes.rb
match 'users/:permalink' => 'users#show', :as => "show_user"
resources :users do
member do
get :followers
end
end
user.rb
attr_accessible :permalink
before_create :make_it_permalink
def make_it_permalink
self.permalink = SecureRandom.base64(8)
end
users_controller.rb
def show
#user = User.find_by_permalink(params[:permalink])
end
def followers
#title = "Followers"
#user = User.find(params[:id])
#users = #user.followers.page(params[:page]).per_page(5)
render 'show_follow'
end
users/_header.html.erb
<%= render 'users/followerstats' %>
users/_followerstats.html.erb
<a href = "<%= followers_user_path(#user) %>">
My Followers ( <%= #user.followers.count %> )
</a>
users/show_follow.html.erb
<div class = "container">
<%= render 'header' %>
<% provide(:title, #title) %>
<div class="row">
<div class="span12">
<h4><%= #title %></h4>
<% if #users.any? %>
<ul class="users">
<%= render #users %>
</ul>
<%= will_paginate %>
<% end %>
/div>
</div>
I got it to work by adding the following:
routes.rb
match 'users/:permalink/followers' => 'users#followers', :as => "followers_user"
users_controller.rb
def followers
#title = "Followers"
#user = User.find_by_permalink(params[:permalink])
#users = #user.followers.page(params[:page]).per_page(5)
render 'show_follow'
end
users/_followerstats.html.erb
<a href = "<%= followers_user_path(#user.permalink) %>">
My Followers ( <%= #user.followers.count %> )
</a>
*****UPDATE:**
Based on suggestion of #Benjamin Sinclaire and post here (Best way to create unique token in Rails?), I fixed up the make_it_permalink in user.rb:
def make_it_permalink
loop do
# this can create permalink with random 8 digit alphanumeric
self.permalink = SecureRandom.urlsafe_base64(8)
break self.permalink unless User.where(permalink: self.permalink).exists?
end
end
Ok you found it while I was writing :)
Also be careful with your make_it_permalink function. There is a tiny chance that 2 users get the same permalink with your code. I suggest you to change it to:
def make_it_permalink
begin
self.permalink = SecureRandom.base64(8)
end while User.exists?(:permalink => self.permalink)
end

'nil' is not an ActiveModel-compatible object that returns a valid partial path

First question, please be gentle :)
I am having trouble creating an index view for a client model that belongs_to the user model with a has_many association.
The error message:
'nil' is not an ActiveModel-compatible object that returns a valid partial path.
Specifically the error refers to the partial on line #11:
/views/clients/index.html
<% provide(:title, current_user.name) %>
<div class="row">
<aside class="span4">
<section>
<h1>Your clients</h1>
</section>
</aside>
<div class="span8">
<% if current_user.clients.any? %>
<ol class="clients">
<%= render #clients %>
</ol>
<%= will_paginate %>
<% end %>
</div>
</div>
/clients/_client.html.erb
<li>
<span class="client-name"><%= client.name %></span>
<span class="client-info">
Extra client info to come.
</span>
</li>
Clients controller:
class ClientsController < ApplicationController
belongs_to :user
def index
#clients = current_user.clients.paginate(page: params[:page])
end
EDIT:
Users controller if it helps...
class UsersController < ApplicationController
before_filter :authenticate_user!
def show
if current_user.admin?
#user = User.find(params[:id])
else
#user = current_user
end
end
def index
if current_user.admin?
#users = User.paginate(page: params[:page])
else
redirect_to root_path
end
end
def destroy
User.find(params[:id]).destroy
flash[:success] = "User destroyed."
redirect_to users_path
end
end
As you can probably tell I am new to rails, but have searched to ensure this hasn't been covered already.
Should you be passing :page => params[:page] to paginate instead?
I declared belongs_to in the clients controller and the model instead of just the model. And didn't notice for two days.

Resources