Rails: notifications using GetStream and Acts As Follower gems - ruby-on-rails

I'm using getstream and acts as follower to build a notification and news feed for my project. When following a certain user, that user is supposed to get a notification of such following. I'm able to follow and unfollow users, but getstream gives the following error:
Something went wrong creating an activity: undefined local variable or method `user' for #<Follow:0x007ffaa70c9398>
Completed 500 Internal Server Error in 37ms
NameError (undefined local variable or method `user' for #<Follow:0x007ffaa70c9398>):
app/controllers/users_controller.rb:160:in `follow_user'
Rendered /usr/local/lib/ruby/gems/2.2.0/gems/actionpack-4.2.0/lib/action_dispatch/middleware/templates/rescues/_source.erb (3.1ms)
Rendered /usr/local/lib/ruby/gems/2.2.0/gems/actionpack-4.2.0/lib/action_dispatch/middleware/templates/rescues/_trace.text.erb (0.8ms)
Rendered /usr/local/lib/ruby/gems/2.2.0/gems/actionpack-4.2.0/lib/action_dispatch/middleware/templates/rescues/_request_and_response.text.erb (0.9ms)
Rendered /usr/local/lib/ruby/gems/2.2.0/gems/actionpack-4.2.0/lib/action_dispatch/middleware/templates/rescues/diagnostics.text.erb (108.1ms)
This if what my follow.rb file looks like:
class Follow < ActiveRecord::Base
extend ActsAsFollower::FollowerLib
extend ActsAsFollower::FollowScopes
# NOTE: Follows belong to the "followable" interface, and also to followers
belongs_to :followable, :polymorphic => true
belongs_to :follower, :polymorphic => true
include StreamRails::Activity
as_activity
def activity_notify
[StreamRails.feed_manager.get_notification_feed(self.followable_id)]
end
def activity_object
self.followable
end
def block!
self.update_attribute(:blocked, true)
end
end
And in user.rb I have:
acts_as_followable
acts_as_follower
and nothing else referencing the Follow model. Any ideas what I'm doing wrong ?
EDIT:
Here is my follow and unfollow code in the users controller. Line 160 is if #follower.follow(#following), and likewise for unfollowing:
def follow_user
#follower = User.find_by_username(params[:username])
#following = User.where(id: params[:following_id]).first
#user = #following
if #follower == #following
respond_to do |format|
flash.now[:warning] = "Cannot follow yourself."
format.js { render file: "/app/views/layouts/notice.js.erb" }
end
end
if #follower.follow(#following)
StreamRails.feed_manager.follow_user(#follower.id, #following.id)
respond_to do |format|
format.js { render file: "/app/views/users/follow.js.erb" }
end
else
respond_to do |format|
flash.now[:info] = "Error."
format.js { render file: "/app/views/layouts/notice.js.erb" }
end
end
end
def unfollow_user
#follower = User.find_by_username(params[:username])
#following = User.find(params[:following_id])
#user = #following
if #follower.stop_following(#following)
StreamRails.feed_manager.unfollow_user(#follower.id, #following.id)
respond_to do |format|
format.js { render file: "/app/views/users/follow.js.erb" }
end
else
respond_to do |format|
flash.now[:info] = "Error."
format.js { render file: "/app/views/users/add_flag.js.erb" }
end
end
end

The stream-rails gem assumes that your model has a user attribute to lookup the actor of the activity. You can change this behavior by implementing the activity_actor method in your Follow model.
For example:
class Follow < ActiveRecord::Base
def activity_actor
self.follower
end
end
This will create activities such as "x followed y" when a follow model is created (as well as the logic that you already have implemented to create actual follow connections between feeds).

Related

Ruby on rails Association Records returns empty But in rails console it returns something

in the registration.rb
class Registration < ActiveRecord::Base
......
has_many :cash_transactions
after_destroy :destroy_cash_transaction
def first_cash_transaction
self.cash_transactions.first
end
def destroy_cash_transaction
if first_cash_transaction.registrations.count == 0
self.cash_transactions.find(first_cash_transaction).destroy
end
end
in cashtransaction.rb
class CashTransaction< ActiveRecord::Base
......
has_many :registrations
so, when I destory the registration, it will destroy_cash_transaction associated with the registration.
In the rails console, I tried:
Registration.find(some_id).cash_transactions
The console returns some records
However, when I tried to delete a registration, it will invoke destroy_cash_transaction, which will call first_cash_transaction, which returns empty records.
Can anyone help me with this? Thank you very much.
-----updated------
in participant controller
def destroy
if #registration.destroy
respond_to do |format|
format.html {redirect_to admin_events_participants_path, :notice => "#{#registration.email}'s registration has been deleted."}
end
else
respond_to do |format|
format.html {
flash[:warning] = print_out_message('form-destroy','registration')
redirect_to admin_events_participants_path
}
end
end
def load_registration
#registration = #event.registrations.find(params[:registration_id])
end

Nested form validation rails 3.2

I have a job and user(devise) form in the same view. When I am trying to submit with errors in the user fields it gives me an exception page with the validation messages. Submitting errors in the job fields works fine!
job_controller.rb
def new
#job = Job.new
if !current_user
#job.user = User.new
end
respond_to do |format|
format.html # new.html.erb
end
end
def create
#types = Type.all
#categories = Category.all
#job = Job.new(params[:job])
#if not logged in creates a user and sign in
if !current_user
#user = User.new(params[:job][:user_attributes])
else
#user = current_user
end
#job.user_id = #user.id
respond_to do |format|
if #job.save
if !current_user
sign_in(:user, #user)
end
format.html { redirect_to #job }
else
format.html { render action: "new" }
end
end
end
job.rb
attr_accessible :user_attributes, :description, :name ....
belongs_to :user
accepts_nested_attributes_for :user
Thanks!
That becuase you are calling, #user.save! which will generate an exception. Also doing it this way won't put the job in the same transaction as User. What you want are nested_attributes:
class Job < ActiveRecord::Base
accepts_nested_attributes_for :user
end
If the user is logged in, don't show that part of the form and filter those params.
See more in the Rails documentation here http://api.rubyonrails.org/classes/ActiveRecord/NestedAttributes/ClassMethods.html
EDIT:
Simplify your controller code, since you're using nested attributes you no longer need to manually create a user.
#if not logged in creates a user and sign in
if !current_user
#user = User.new(params[:job][:user_attributes]) # this is no longer needed
else
#user = current_user
end
#job.user_id = #user.id # this is redundant
To something more like:
# if logged in, manually assign the user (also you may want to reject any user attributes)
#job.user = current_user if current_user

Get error after destroy action No Method Error in Controller#index, and log out

I have two models. Hotel model:
class Hotel < ActiveRecord::Base
attr_accessible ...
belongs_to :user
end
User model:
class User < ActiveRecord::Base
devise ...
has_many :hotels
end
hotels_controller.rb
class HotelsController < ApplicationController
def index
#hotels = current_user.hotels
end
def show
#hotel = Hotel.find(params[:id])
end
def new
#hotel = Hotel.new
end
def create
#hotel = Hotel.new(params[:hotel])
#hotel.user = current_user
if #hotel.save
redirect_to hotels_path, notice: "Nice, you added new hotel " + #hotel.title
else
render "new"
end
end
def edit
#hotel = Hotel.find(params[:id])
end
def update
#hotel = Hotel.find(params[:id])
if #hotel.update_attributes(params[:hotel])
redirect_to hotels_path, notice: "Hotel " + #hotel.title + " was successfully updated"
else
render "edit"
end
end
def destroy
#hotel = Hotel.find(params[:id])
#hotel.destroy
redirect_to hotels_path, notice: "Hotel " + #hotel.title + " was deleted"
end
end
When I signed in I'm creating hotel with some fields, after submit it's rederect me to a list of hotels and it's nice. But when I try to delete some of the hotels I get
NoMethodError in HotelsController#index
undefined method `hotels' for nil:NilClass
and after that when go to the home page(root) my session is over and user is logouted. But! Hotel was successfully destroyed. Something with index action... What i do wrong? Have any ideas?
Just add in your layouts/application.html.erb this line in a head block
<%= csrf_meta_tags %>
The problem is that current_user is nil and failing when you try to get hotels on it.
current_user.hotels
So the question is: what sets up current_user?
You're using devise - can you check what you're doing on hotels-index? do you get automatically logged in for that or does it assume you're sometimes logged-in and sometimes not and it's failing to pick that up?

Nil class error

I want to display the related products to a certain need, just the picture and the name nothing more depending on the categorie
here is mu controller
class RelatedneedsController < ApplicationController
def index
#relatedneeds = RelatedNeed.all
respond_to do |format|
format.html # index.html.erb
format.json { render json: #relatedneeds }
end
end
def show
s1 = '#need.category.name'
s2 = '#relatedneed.category.name'
if s1.eql?(s2)
#relatedneed = relatedneed.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.json { render json: #need }
end
end
end
def get_name
#relatedneed.name
end
end
and this my model
class Relatedneed
include Mongoid::Document
include Mongoid::Paperclip
mapping do
indexes :name
end
field :name, type: String
belongs_to :category
belongs_to :user
end
and this is show.haml file
%h1
%b= #need.name
#container{:style => "width:1000px"}
#desc{:style => "height:400px;width:400px;float:left;"}
=image_tag #relatedneed.photo.url(:normal)
this is my index.haml file
%h1= #relatedneed.get_name
#container{:style => "width:1000px"}
#desc{:style => "background-color:#EEEEEE;height:400px;width:400px;float:left;"}
= link_to "Check Need", new_need_path
I don't know if their is something missing and i get this error
NoMethodError in RelatedneedsController#index
undefined method `key?' for nil:NilClass
Your index.haml has #relatedneed.get_name but you have not set #relatedneed in your controller, only #relatedneeds. Is it as simple as that?
Also, your show method in the controller makes no sense to me. You have put your instance variables inside strings! You need to set your instance variables with a database query via the model first. Your get_name method looks like it belongs in a model as well rather than a controller.

build_association working?

I have two models with a one-to-one association.
class User < ActiveRecord::Base
has_one :setting
end
class Setting < ActiveRecord::Base
belongs_to :user
end
Each model has plenty of fields and user is used quite extensively by a non rails external server, which is why I have separated the tables.
I am trying to use the build_association but all I get is undefined method `build_setting' for nil:NilClass. I want to do this because I want a single form with fields from both models to setup a new user.
In my user controllers new method I try this:
def new
#user = User.new
#setting = #user.setting.build_setting
respond_to do |format|
format.html # new.html.erb
format.xml { render :xml => #user }
end
end
Which throws:
NoMethodError in UsersController#new
undefined method `build_setting' for nil:NilClass
Why? According to the api docs this is the way to do it.
Doing this seems to work, but its not the right way (or is it?):
def new
#user = User.new
#setting = Setting.new
#user.setting=#setting
respond_to do |format|
format.html # new.html.erb
format.xml { render :xml => #user }
end
end
You need to use:
#setting = #user.build_setting
This is after an edit, so if you like this answer, accept Mahesh's below.
In your users model add
class User < ActiveRecord::Base
has_one :setting
validates_associated :setting
end
and then use
#setting = #user.build_setting

Resources