hey guys so i'm having issues adding a Like/Dislike function to my bookmarks on my page.
basically i have a snippet of code given to me that lives in my User model:
def liked(bookmark)
likes.where(bookmark_id: bookmark.id).first
end
however when i am running the server and clicking on the topic to show the associated bookmarks, i keep getting the
undefined method `id' for nil:NilClass
my question is... firstly what is going wrong here? and secondly, whats the difference between bookmark_id and bookmark.id?
im pretty sure id doesn't exist for bookmark... and if not... how would i add it?
ive tried via migration, unfortunately nothing great came from that
use this code:
def liked(bookmark)
likes.where(bookmark_id: bookmark.id).first if bookmark.present?
end
You are getting id for nil:NilClass error due to object is not present.i.e bookmark object is nil.
bookmark_id is the field name for the bookmark class.And bookmark.id returns the id of the bookmark object, only if the object is present.
bookmark.id raises an exception.
Ensure bookmark instance is passed to the liked method and is not nil
You need to ensure that your bookmark argument is not nil.
You could try the following code
def liked(bookmark)
likes.where(bookmark_id: bookmark.try(:id)).first
end
or an even better version
def liked(bookmark)
likes.find_by(bookmark_id: bookmark.try(:id))
end
Above code will return a nil object or first like
To answer your second question, bookmark_id is an column name here for your Like model whereas bookmark.id is a method call on bookmark object.
You can try the following.
def liked(bookmark)
likes.where(bookmark_id: bookmark.id).try(:first) unless bookmark.blank?
end
Related
I'm trying to follow a tutorial to create a messaging app but while creating a conversation controller I faced an error. My goal is to check whether a conversation between the current_user and the selected user exists or not. If it doesn't exist then I want to create a new one.
but when I tried this I got the error from the bellow. It would be a big help.
The error log
NoMethodError (undefined method `include?' for nil:NilClass):
app/controllers/conversations_controller.rb:30:in `conversated?'
My controller from Conversations
def create
#conversation = Conversation.get(current_user.id, params[:user_id])
add_to_conversations unless conversated?
end
private
def conversated?
session[:conversations].include?(#conversation.id)
end
Let me know if you need any other parts added to the question. Thanks in advance.
When you are first calling session[:conversations], the value seems to be nil and such include? is not a method that nil knows how to respond to. I think you can make a small tweak in that check like so:
def conversated?
session[:conversations]&.include?(#conversation.id)
end
The & is a safe navigation operator where the method is only called if a value exists.
I have a User model that has an attribute called country. This attribute is set by a method called methodA.
Somewhere else in my code I may try to access User's country attribute and it might be blank if methodA never ran.
What I'm looking for is to run methodA if I try to access User's country attribute and it's blank.
I tried something like that in my Model :
def country
c = read_attribute(:country).presence
if c.blank?
methodA
else
return c
end
end
But I get an error when it first runs. If I reload the page, country has been set on the previous run (even tho the error) and it's all good.
I would love it to work on the first run and avoid the error page tho...
Thanks in advance for your help
You can just call super
def country
super.presence || "do whatever"
end
presence will check present? and if present? it will return its receiver; otherwise it returns a false-y value (nil).
Remember that if possible you should be setting a database default.
I have managed to achieve my goal using this :
class User < ApplicationRecord
after_find :check_country
def check_country
if country.blank?
methodA
end
end
def methodA
...code
end
end
It does work but I'm not sure if this is ideal... Because check_country will be executed everythime a User is fetched... Even if country is set.
I would prefer it to run only if country is blank.
Any idea ?
I want to disable all link of users at a time after deactivating users. So, for that I wrote a code like this
def link_to(*user)
if user_link_disabled?(user.id)
return nil
else
super
end
end
def user_link_disabled?(user_id)
User.where(activation: false).pluck(:name).include?(user_id)
end
But I am getting this error
undefined method `id' for #<Array:0x007efee4667d00>
Could anyone please help me on this?
I would add a column to your users model:
deactivated => type boolean
user.deactivated? #will return true or false
In your view you can then use link_to_unless
link_to_unless(user.deactivated, name, options = {}, html_options = {}, &block)
I don't know the scope because you didnt display anymore info but it could just be user_id in your if statement or try id[params[:id] instead of user.id but I'm not sure with out more context.
IN following method
def user_link_disabled?(user_id)
User.where(activation: false).pluck(:name).include?(user_id)
end
You are going to pluck name from user table records but you are checking include? for user.id, I think you should pluck id instead of name.
First of all, I am not gonna comment on your preferred code/method for overriding the the link_to helper. There is not much context available for that.
But to solve the particular error you are getting:
Your are defining method like this def link_to(*user) .
Here *user means it is expecting an Array as argument to the method and using the Ruby splat(*), it is converting it to normal arguments.
So if you call this as link_to [1,2,3], it will be same as calling a method with 3 arguments. That is link_to (1,2,3) but the argument user will be an Array.
So in here if user_link_disabled?(user.id), you are calling a id on a Array data type. That's why you are getting an error.
Depending on your use, either remove the * from method definition,
or
Use looping, if you are going to pass multiple users data to method, like:
def link_to(*user)
user.each do |u|
if user_link_disabled?(u.id)
return nil
else
super
end
end
end
As I mentioned in beginning, I don't know much about the context. So can not comment about the right way but if I may suggest, then I would suggest to use a custom helper for all user routes. like below pseudo code:
def link_to_user(user)
deactivated = user.deactivated?
if deactivated
# render some disabled link
else
# render link
end
end
With the koala gem I am trying to count checkins for a page. I am using rails.
In my user.rb I have a method for getting a new connection to the Facebook graph:
class User < ActiveRecord::Base
def facebook
#facebook ||= Koala::Facebook::API.new(oauth_token)
end
end
In my school.rb I have a method for counting the checkins:
class school < ActiveRecord::Base
def count_checkins(name)
checkins = #facebook.fql_query("SELECT checkins FROM page WHERE name = #{name}")
end
end
And I am calling it from the view like this:
<%= #school.count_checkins(#school.name) %>
But I get the following error:
undefined method `fql_query' for nil:NilClass
Dont really understand why I get this error, any help would be wonderful.
It looks like you haven't actually created the #facebook object inside your School model. We'd need to see the rest of your school.rb file to know for sure. I'd suggest you create the object inside your School.initialize() method like so:
def initialize(oauth_token)
unless oauth_token.nil?
#facebook = Koala::facebook::API.new(oauth_token)
end
end
In order for this to work, you'll need to pass the desired oauth_token to your School.new() call. Then you'll have one #facebook object for each School.
Edit
After looking at the gist, I realized that you had actually intantiated a User object, and called the facebook method on that. That is actually the better way to do it. The problem is, you're using #current_user, which would have to be setup as a property of the school model. You probably meant to use the helper function current_user instead.
def count_checkins(name)
u = current_user
u.#facebook.fql_query("SELECT checkins FROM page WHERE name = #{name}")
end
Try that and see what happens. At the very least, you should get a different error message.
Edit 2
So, now I'm thinking the current_user function should be called in controller code, not model code. This is because the current user is something that doesn't really exist except as part of an active request. Therefore, we should take User u as a parameter to the count_checkins function like so:
def count_checkins(name, u)
u.facebook.fql_query("SELECT checkins FROM page WHERE name = #{name}")
end
You'll need to change the code where you call count_checkins() too:
count_checkins(name, current_user)
That should do it. Let's see!
First off, the exception in question:
undefined method '_view_paths' for nil:NilClass`
The related routes:
get 'payments/index' => 'payments#index'
get 'payments/class' => 'payments#class'
get 'payments/kids' => 'payments#kids'
get 'payments/donate' => 'payments#donate'
The associated controller:
class PaymentsController < ApplicationController
def index
end
def class
end
def kids
end
def donate
end
end
So, the exception occurs every time I try to access one of the routes. The views for the routes described above are the simple ones generated with scaffolding and use no other rails API calls. I can't seem to find any other information on this '_view_paths' method. The only assumption I can make thus far is that the proper view isn't being found, but all views reside exactly where expected according to rails conventions (app/views/payments/*).
Has anyone stumbled upon this issue and found a solution?
You can't define a method named "class" as it's already a reserved method to refer to the object's class, for example:
Object.new.class #=> Object
Technically I suppose you can override it (as you have), but doing so is mostly likely going to have some bizarre consequences unless you know what you're doing.
The error is probably happening when the code tries to call something like self.class._view_paths. It expects to be calling PaymentsController._view_paths. However, you've overridden the instance method class with an empty method returning nil, hence the nil exception.