I am currently struggling with this piece of code
#play = current_user.playlist.find_by_id(params[:id])
What does current_user.playlist.find_by_id() mean? How can I trace this code to find current_user, playlist and find_by_id() function?
You could be using devise, if that is the case, current_user returns an instance of class User which is the currently logged in user. Or nil if there is no logged in user.
playlist is a method defined in class User, you should find this class in app/models/user.rb, usually this method would be defined with:
has_one :playlist
or:
belongs_to :playlist
find_by_id is a method defined by Rails for class User, you won't see this directly in file. It is created when you have something like this:
class User < ActiveRecord::Base
ActiveRecord::Base creates a lot of methods more.
Debug your code
I would print each part of the sentence
p current_user
p current_user.playlist
p params[:id]
p current_user.playlist.find_by_id(params[:id])
and check results in my server console, you could spot which of these is the first nil.
In Ruby, everything is an object, and objects have methods. Objects also have types.
Your top-level object there is current_user. This is an instance of some class - you can find out what kind by looking at current_user.class. I suspect you're going to find that it's an instance of User.
So, you find where your User is defined. This is likely a model, defined in app/models/user.rb. This model will specify a number of attributes and associations. In this case, you likely have a has_many :playlists association. What this does is set up an association between a User instance and a number of Playlist instances. Given a user instance, user_instance.playlists accesses this association. Your Playlist model will have a user_id field that associates a playlist with a user record. You can read more about associations in the relevant documentation.
Finally, this association will have a number of methods from Rails. ActiveRecord has a standard set of finders, as well as some "magic" finders like find_by_id, which infer the field to find from based on the method name. find_by_id(params[:id]) is functionally equivalent to something like find_by(:id => params[:id]), but it's a little more English-y. You can read more about this in the Dynamic Finders method of the documentation.
find_by_id will generate the SQL necessary to find the playlist records with that ID that also have a user_id matching current_user's ID. If it finds a matching record, it will instantiate a Playlist record with the data it retrieved and return it. If no matching record is found, it will return nil.
Related
Is there any way to initialize a record from session. for e.g I have a organization object and I put this in session object like
session[:organization] = organization
Now I made a custom method current_organization (I know about devise) like
def current_organization
Organization.new(session[:organization])
end
This will return organization object. My organization belongs_to a team a devise model and team has_many :organizations but when I call
current_team.organizations.includes?(current_organization)
in view. It is returning false even if it is included in team's organizations but doing this
current_team.organizations.reload.includes?(current_organization)
is returning true. I set the session variable with organization object before calling view where i am using above method. Is there any thing which I missed like I am not able to figure out the reason for not returning true even it is included?
Try saving the record first.
Until you save it into the database, it is likely not to show up when you query for the team's organization children.
session[:organization_id] = organization.id
def current_organization
Organization.find session[:organization_id]
end
Ok after some googling i found that instead of using
Organization.new(session[:organization])
I should use
Organization.instantiate(session[:organization])
From apidock I found that
instantiate(attributes, column_types = {}) public
Given an attributes hash, instantiate returns a new instance of the
appropriate class. Accepts only keys as strings.
For example, Post.all may return Comments, Messages, and Emails by
storing the record’s subclass in a type attribute. By calling
instantiate instead of new, finder methods ensure they get new
instances of the appropriate class for each record.
This question RAILS: How to get has_many associations of a model tells how to find all the associations of a Class. I want to do this for an instance of the class. In particular I have a User model, and when I setup a User instance, it has a number of associations e.g. user.profile, user.plans etc. I want to check all the associations have been successfully set up for a particular user instance. How do you do this?
Based on the link you provided you should be able to accomplish what you want by doing this:
User.reflect_on_all_associations.map { |assoc| assoc.name }.each do |assoc|
association_object = user.send assoc
#note this is the user instance not the class.
# do whatever you want with association_object. check if nil?
end
What the code does, it to iterate through the list of association name keys returned the link you provided and then use it to call the "method" (meaning the association) by using send.
Hope that helps
USECASE:
Consider the following example.
Class Foo < ActiveRecord::Base
belongs_to :user
attr_accessible :title
end
Class User < ActiveRecord::Base
has_many :foo
attr_accessible :name
end
If a logged-in user creates Foo, it will be associated to its user record. If a not logged-in user creates Foo, it wont be associated to any user. This is just an example and I have a lot of similar use cases in my application.
PROBLEM:
The problem is my view code gets cluttered with a lot of if conditions and ternary operations like,
<% foo.user ? foo.user.name : "not set"%>
CURRENT SOLUTION:
To overcome this, I am using the null object design pattern. The User class defines a NullUser object (whose name will be set to "not set"). If a foo object does not have user object, it will return a NullUser object. I have overridden the user method in Foo class which does the nil check.
QUESTION:
Is there a better solution to this?
Is there a gem which facilitates
the null object pattern for rails active record models.
This sounds like the perfect case for a decorator that wraps your user object. All the logic about what to display goes in there; all your view cares about is that it can spit out the object's name.
Draper works well for decorators in Rails.
And a Railscast for good measure.
One potential solution would be to set a default value and associate it with a guest user. That way it would be overridden when a user was present, but would mean there would always be a value when you call .user.name
I have a Record model and in order to edit this model, you must be logged in as an instance of Admin. I would like to have a column called last_modified_by which points to the Admin who last modified the Record. In the database, I was thinking it would be good in the records table to add a column that holds the Admin's id; however, the only way I know how to do that is with an association. These two models are not associated with each other so an association doesn't make a lot of sense. Is there any other way I might be able to accomplish this task without resorting to associations? Any advice would be much appreciated!
Hmm, I think the association is a good tool here. You might want to try to hack it somehow but I think nothing you can conjure up will ever be as good as an association via a foreign_key(also so fast). But perhaps you would like to name your association and do something like:
class Record < ActiveRecord::Base
belongs_to :culprit, :class_name => 'Admin', :foreign_key => 'last_modified_by'
end
or give it some more senseful naming?
You could create an Active Record before_save callback. The callback would save the admin's id into the last_modified_column. This would make sure the admin id is saved/updated each time there is a change to the model.
For example, assuming admin is #admin:
class Record < ActiveRecord::Base
before_save :save_last_modified
def save_last_modified
self.last_modified_column = #admin.id
end
As for getting #admin, you could employ a method similar to this, and set #admin = Admin.current (like User.current in the link) somewhere in the Record model.
Hey I am stuck with my orientation in rails.
I got a User model, a Course Model and a CourseEnrollment Model.
When I want to add a link in my Course Index View like
link_to 'join' CourseEnrollment.create(:course_id => course.id, :user_id => current_user)
Does this create method belong to my Model? I am confused because in my User Model I defined a method that uses role_assignments.create(.....). What is the difference between these 2 create methods? I cant use course_enrollments.create by the way. Thx for your time
I'm a bit confused as to what you're asking, but I'll try my best.
(First of all, in your example, current_user should probably be current_user.id.)
When you call CourseEnrollment.create, you are simply creating a new CourseEntrollment model with the specified attributes.
Assuming that your User model has_many :role_assignments:
When you call #role_assignments.create from within your User model, Rails automatically creates the association for you (e.g. sets the user_id to the id of the user). This doesn't have to be done within the model itself, though:
current_user.role_assignments.create(...) # automatically sets the association
Assuming that your User model also has_many :course_enrollments, the following will create a CourseEnrollment model and automatically associate it with the current user:
current_user.course_enrollments.create(...)