RoR scope issue - ruby-on-rails

I have a users table. It contains a field "user_type".
I added the following scope stmts to the user.rb file:
scope :uemployee, where(:user_type => 'employee')
scope :uclient, where(:user_type => 'client')
scope :ucontractor, where(:user_type => 'contractor')
I created a view and I would like it to list he employees.
Here is the code I'm trying to use:
<% #users.uemployee.each do |user| %>
But, I get "undefined method `uemployee' for nil:NilClass"
What am I doing wrong?
Thanks

Looks like you wanted to do this:
<% User.uemployee.each do |user| %>
But this is considered to be a bad practice. You have to prepare you data in a controller and a view just cycles through it:
# in a controller's action
#users = User.uemployee
#in a view
<% #users.uemployee.each do |user| %>
But even this isn't the best approach. If you create the file views/users/_user.html.erb which shows the info about a particular user (current user will be available as a simple user variable, without the #) then you can simply write:
# in a view
<%= render #users %>
# remember, #users variable was set in your controller
then Rails will cycle through all the users "inside" the #users variable and show them one-by-one.

Your #users collection is nil

Related

Rails undefined method 'job_app'

So i want to create the view:
1. for normal user, to see it job app status:
def index
#users ||= current_user
#job_apps = #users.job_app
end
It works perfectly on view.
2. Trouble (job_app method undefined) : create view for admins so they can see all candidates:
def empl
#users = User.all.where(:user_type => 'candidate')
#job_apps = #users.job_app.all
end
Note : without #job_apps i can see all the users as well.
I'm going to make a bit of an educated guess here: job_app is indeed a method of the User class, but what you're dealing with in your controller's empl method is not an instance of User, but rather, an instance of ActiveRecord::Relation, which is more or less an array of User objects. User.job_app works because job_app is a member of User, but not of ActiveRecord::Relation.
To achieve what you want, you have to do some iterating through the elements of that array within the view associated with your empl method.
controller code:
def empl
#users = User.all.where(:user_type => 'candidate')
end
view code:
<% #users.each do | user | %>
<%= user.job_app %>
<% end %>

Uninitialized constant {"contrller name"}Controller

I am trying to create a new page in my Rails view.
My view is: histories/index.html.erb
My controller is: process_controller.rb
The new page I am trying to create is: histories_paid_out
In my routes.rb, I have:
get "process/histories_paid_out" => "process/histories_paid_out", :as => "histories_paid_out"
And in my process_controller.rb, I have:
def histories_paid_out()
payments = Payments.all
end
And then finally I am calling the controller in my view like this:
<% #histories.each do |history| %>
<%= link_to 'View paid out payments', histories_paid_out_path() %>
<% end %>
But when I cliked the "View paid out payments" link, my Rails app gave me this error:
What's wrong? It is so weird because I think my configuration and setup is already correct.
You should write the singular version of the model. Try this:
def histories_paid_out()
payments = Payment.all
end
Also you will need to define the histories variable somewhere.
Finally, payments will not be available in your view unless you change the scope by calling it #payments instead.

Calling specific instances of a user's objects on their show page

I'm trying to list a user's wanted ads in their show page when they access /users/:id.
In my controller I have:
def show
#user = User.find(params[:id])
#wanted_ads = WantedAd.where(:user_id => params[:id])
And in my show.html.erb I have:
<%= #wanted_ads %>
Binding.pry says #wanted_ads is nil. On the actual page I get #<ActiveRecord::Relation:0x007fa3b5a93408>. This is seemingly a simple thing I'm trying to do -- what am I missing?
The where function returns a ActiveRecord::Relation.
So, you can call first to get the first element, last to get the last one or all to get all elements stored in an array called #wanted_ads.
#wanted_ads = WantedAd.where(:user_id => params[:id]).all
You can then go through this array and choose the attributes you want to pass to the view for each element.
Just a tip:
You should have in your User model an ActiveRecord relation, like this:
has_many :wanted_ads
And in your WantedAd model, like this:
belongs_to :user
And with this, you have a relation of one-to-may.
Then, you can do this:
def show
#user = User.includes(:wanted_ads).find(params[:id])
end
And then, in your view:
<% #user.wanted_ads.each do |wanted_ad| %>
<%# do something %>
<% end %>
where returns a collection of objects, not just a single object. So depending on what's returned you'll want to either call first to get the single instance that ought to return, or call each to iterate over the wanted ads and display them on your page.
You're seeing an instance of ActiveRecord::Relation in pry because of the underlying query mechanism that lazy loads the results. More details can be found here.
Assuming your #wanted_ads is not nil and you want to loop through all the wanted ads...
<% #wanted_ads.each do |wanted_ad| %>
<%= wanted_ad.some_attribute_of_wanted_ad %>
<% end %>
I would also suggest you be aware of SQL injection with the following code in your controller.
#wanted_ads = WantedAd.where(:user_id => params[:id])
As it should be
#wanted_ads = WantedAd.where(":user_id => ?", params[:id])

Loop error in Rails 3

i want to display all posts in Post table with say id=5 ......
controller
user_controller.rb
class UsersController < ApplicationController
# other methods are also present...
def profile
uid=session[:userid] #session contains userid,it is stored in uid....Eg:5
#post=Post.find_by_userid(uid) #Display all posts with userid=5 in Post table.
end
end
view
profile.html.erb
<h1>In Profile</h1>
<%=session[:test]%>
<% #post.each do |p|%>
<%= p.title%>
<%= p.body%>
<%= p.tag%>
<%end%>
when i execute i get an error like....
Showing /Users/Vineeth/QA4/app/views/users/profile.html.erb where line #3 raised:undefined method `each' for #
Please help me fix the error......thanks.
Post.find_by_userid(uid) is same as Post.where(:userid => uid).first, return only one record.
You should use Post.where(:userid => uid)
You're using Post.find_by_user(uid) which is not something you can iterate over. It only returns a single record.
Use something that returns a collection, like Post.where(:userid => uid)

Using a block to name and create instance variables [Ruby-on-Rails]

I'm working on a CRUD interface for managing users in my application. I have a constant User::ROLES that is an array with the names of valid user roles in my app (admin, teacher, student).
What I'm wanting to do is, in the index action of the controller, have a block that iterates through the ROLES constant and creates a scoped instance variable from #users (which is already initialized before the block). Here's what the index method looks like so far:
def index
#users = user.all
##students = #users.where(:role => "student") # This works by itself
User::ROLES.each do |r|
#r = #users.where(:role => r.to_s)
end
end
So I want to be able to name the instance variable by what's passed through the block, so #r creates #admin, #teacher, etc. Since I'm new to ruby and rails, I don't quite understand the syntax for doing this. Who knows? There's probably a better way to do it anyways.
EDIT
Just to let everyone know, I'm hoping to use this in the view on the index action to display a list of users grouped by their role. Of course, it will be used in other ways too throughout the CRUD interface, which is why I didn't clarify the use-case earlier, since it's multi-purpose.
This is probably a bad idea. If you change a role in your model, you will need to update your view accordingly to use a different instance method. A better way to handle this would be to simply group users by their role:
#users = User.group(:role).all
Which would give you a hash with keys named after each role that you could easily use to build a dynamic view:
<% #users.each_pair do |role, users| %>
<h2><%= role.to_s.titlelize %></h2>
<% users.each do |user| %>
...
<% end %>
<% end %>
You can also access users with a specific role if needed:
<h2>Admin users:</h2>
<%= #users[:admin].map(&:name).to_sentence %>

Resources