Rails Controller Index Only Display Objects with Association - ruby-on-rails

I have a Rails model called User. There are two different types of users. Some users have company_profiles in a separate table.
In my controller for my page view, I'd only like to display those users who have company_profiles. I'd also like to display their user info and their company_profile info too.
I'm not sure how to handle this in my controller and view.
What should be in my index method?
def index
#users = User.scoped # ?????
end
And how do I loop through each user with a company profile on the index page?
<% #users.each do |user| %>
<p>
<%= user.email %>
<%= user.company_profile.poc_first_name %>
</p>
<% end %>

Now you mentioned you want to show users only for which company_profile exists. So in your controller method following should be in the index method
def index
#users = User.left_outer_joins(:company_profile).where("company_profiles.id is NOT NULL")
end
Then in your views you can get company_profile's poc first name as follows
<% #users.each do |user| %>
<p><%= user.email %>
<%= user.company_profile.poc_first_name %>
</p>
<% end %>

Making an INNER JOIN when loading the records from the database should work:
def index
#users = User.joins(:company_profile)
end

Related

How to use include or join into with a each method

I need a little advice about the join and includes methods.
I display a list of groups in the index view. Each has a modal associated, and, in this modal, I would like to display the requests associated to this group. Normally, I'd use #requests = group.requests, but would like to use join for sending just one request to my database.
Since I'm in the index view, I don't have a #group in my action.
controller:
def index
#groups = current_user.groups
end
view (index):
<% #groups.each do |g| %>
<MODAL>
<% #requests = g.requests %>
<% #requests.each do |r| %>
<%= r.date %>
<% end %>
</MODAL>
<% end %>
I guess I can also use join and include for #groups, but there is already one SQL request, so I'm good with it.
In your controller, add includes like this to preload requests and avoid n+1 queries.
def index
#groups = current_user.groups.includes(:requests)
end
View is fine, but you can also write as:-
<% #groups.each do |g| %>
<MODAL>
<% g.requests.each do |r| %>
<%= r.date %>
<% end %>
</MODAL>
<% end %>

Devise - how to show user's post

I use Devise gem for authentication.
In database I have users table and posts table in my database schema (and Post controller).
In post controller I want to find all posts assigned to specific user. I have user_id in posts table.
How to get all user's posts or how to check if specific post is assigned for SIGNED IN user.
I thought about something like this (of course is only pseudocode:
current_user.id == Post.where(params:[post_id]).user_id
So how to get current user id in Devise and how to check the current user id is the same like eg. user_id assigned to viewing post (I want to add 'edit' function when current user is post owner) and how to find all post which current user is owner.
Associations
Firstly, your user_id column in your posts table is what's known as a foreign_key
Foreign keys are used in relational database systems to give you the ability to call associative data from a single record. Simply, it means that you'll be able to use the ActiveRecord associations to call the data you require, rather than having to call it individually:
#app/models/user.rb
class User < ActiveRecord::Base
has_many :posts
end
#app/models/post.rb
class Post < ActiveRecord::Base
belongs_to :user
end
This will give you the ability to use the following call:
#app/controllers/posts_controller.rb
class PostsController < ApplicationController
def index
#posts = current_user.posts
end
end
You'll be best served looking up the has_many association:
Fix
In regards to showing your posts for your users, you need to be sure that you have the correct "flow" set up. What I mean is you need some condition to know whether your user is signed in & that #posts is set:
#app/views/posts/index.html.erb
<% if #posts.present? %>
<% #posts.each do |post| %>
<%= post.title %>
<% end %>
<% end %>
Maybe this is the first time you use Devise. You can access current_user inside controllers or views. I imagine you could do something like this
In controller (posts_controller.rb):
#posts = current_user.posts
In view (posts/show.html.erb, I guess):
if current_user.id = #post.current_user
#render something here
end
Get all post which current user is owner.
#posts = Post.where(:user_id => current_user.id)
and on your view
<%-# commented : checking if #posts is empty -%>
<% if #posts.empty? %>
<span>Sorry, post is empty </span>
<% else %>
<%= #posts.each do |p| %>
<% if p.user_id == current_user.id %>
<% link_to "edit", edit_path(p) %>
<% end %>
<% end %>
<% end %>
There are many ways you could get current_user posts. I'll go the long way.
we need
an action
an action view and a partial
a route
a link_to
* action *
def my_posts
#posts = current_user.posts.all.order(created_at: 'DESC')
end
* view *
my_posts.html.erb
<% if #posts.present? %>
<%= render 'posts' posts: #posts %>
<% else %>
<h1>You don't have any posts yet! create one</h1>
<% end %>
_posts.html.erb
<%posts.each do |post| %>
<%= post.title %>
<% end %>
index.html.erb
<%= render 'posts' posts: #posts %>
route
get 'post' => 'posts#my_posts', as: :my_posts
link_to
<%= link_to 'My posts', my_posts_path %>
I may be late but someone can find it useful :)

how do i display an objects attributes from a different table in rails

Apologies if my terminology is off here.
I have a model for Users. I have a model for Products. Users have many products and Products belong to Users.
I am trying to have a Users index page that shows all Users and their associated Products with links to the individual User pages. My SHOW page is operating as I expect but I don't know how to show the User's Products on the index view.
SHOW (this works)
Controller
def show
#user = User.find(params[:id])
#product = #user.products
end
View
<%= #user.name %>
<% if #user.products.any? %>
Product
<%= render #product %>
<% end %>
Product Partial (referenced above)
Serial Number: <%= product.serial %>
INDEX (this does not work)
Controller
def index
#users = User.paginate(page: params[:page])
#product = #users.product #trying to show
end
View
I am at a loss here. Anything I've thought made sense doesn't work for me.
I would like to do something like
<%= user.product.serialnumber %>
or
<%= user.product.id %>
How do I show attributes of the User's Products in a view? Why does it work in a partial in my SHOW action/view but not in my INDEX action? Do I have to use a partial?
For your index action, #users is a collection of users whereas in your show #user is a single user object.
When you say, #users.product, you are calling product on collection object and not user object. So what you have to do is, iterate #users collection in your view and call product on the object
Something like
<% #users.each do |user| %>
<%user.products.each do |product|%>
<%= user.name%>
<%= product.serialnumber%>
<%= product.id%>
<%end%>
<% end %>

Feed of all posts from all users

I am trying to Implement a feed of all post from a multi user blog. I want to know where to define this method and how to define it to be as "RESTFUL" as possible.
I am thinking of putting it in the posts index view but the problem is i dont have access to the users name attribute that created that post. The index action currently looks like this
def index
#posts = Post.all
end
and doing this:
def index
#user=User.find(params[:user_id])
#posts = #user.posts.all
end
raises an error " Couldn't find User without an ID "
App info:
I have a users resource and a post resource (nested in the users). That is pretty much it.
Thanks
Clarification:
Thanks guys for the assistance so far. My controllers index action is defined as follows
def index
#users = User.all
#posts = #users.collect { |user| user.posts }.flatten
end
The issue i am having is displaying the posts users name in the view. for example this works but only displays the posts attibutes:
<% #posts.each do |post| %>
<ul>
<li> <%= post.title %>
<%= post.content %>
<%= user.name %> or <%= #user,name %> #This does not work
</li>
</ul>
I am not sure if i wrote the block correctly. Hope this clarifies things
You can do something like this:
def index
#posts = Post.includes(:user)
end
# view
<ul>
<% #posts.each do |post| %>
<li>
<%= post.title %>
<%= post.content %>
<%= post.user.name %>
</li>
<% end %>
</ul>
You should be visiting the wrong URL.
First, check your parameters in your server console, you should not see user_id param.
To set this param, use the correct route
user_posts_path(an_user_instance)
I suppose you have in routes:
resources :users do
resources :posts
end
First you need to query the users that you want...
def index
# For example...
#users = User.all # or...
#users = User.find_by_group_id(params[:group_id]) # etc...
# Then, from your users, you need to collect the posts...
#posts = #users.collect { |user| user.posts }.flatten
end
This would get an array of each users posts, then flatten it to a single array. At that point you can then sort the array to whatever you want.
I don't know what exactly you're looking for, but these are just some ideas. Depending on how you're app is structured (and the groups of users are organized), you'll likely want to use some sorted of nested resource like juanpastas posted.

Looping through a related model and comparing id's

The relation is that a user has many treatments and a treatment belong to user, one-to-many.
Now i want to print out all the users that have this particular treatment
Inside my treatments show view i have this double loop
<% User.all do |user| %>
<%= user.treatments.each do |t| %>
<% if (t.id).to_i == (#treatment.id).to_i %>
<%= link_to user.name, user_path(user) %><br />
<% end %>
<% end %>
<% end %>
if i change <% User.all do |user| %> to <%= User.all do |user| %> it prints out everything in my users table
can you guys spot why im not getting any users ?
i put a message in the beginning of the inner loop and it didnt display either, guess the problem is there but im not seeing it
.all returns an array. Array doesn't accept a block. Most likely, you want to do .each but forgot to write it. Try this:
<% User.all.each do |user| %>
but a better way is to not iterate all users like this, but get the correct list from the database directly.

Resources