ruby on rails get table row by two column conditions - ruby-on-rails

For instance, I have two tables in database, Users and Microposts. The Users table stores all the users and has two columns, id and name; the Microposts table stores the posts made by the Users and has three columns: id, post_content and user_id (These two tables, of course, have the timestamp as each entry is created). So basically what I want is have a view page that displays the information stored in Users (id and name) plus the last post created by the corresponding user.
One way I'm thinking of doing is to have it being processed right at the user view page (located in, for example, app/views/Users/index.html.erb). Since I'm probably going to loop through the Users table like this
<% #Users.each do |user| %>
id = user.id
<!-- Do such and such -->
<% end %>
and while looping through the Users table, use the user.id to get the latest post made by the user.
Second way is to basically implement such that the Users table has another column that store the latest post information and updates each time when a transaction is made to the database. So then when implementing the latest post can just be accessed as an attribute.
However, I don't really know which way is better nor how to implement either way...
Any suggestion?
Thanks in advance!
Edit:
Sorry, there is a typo. It's "two tables and one database"

Similar to the other answers but I wanted to add an important little piece that I feel is commonly overlooked. Including the association on the first call to the database.
# not sure the scale of your project but I would paginate #users
# by using includes you prevent the N+1 issues
<% #users.includes(:microposts).each do |user| %>
id = user.id
user.microposts.last
<% end %>
For some documentation on this:
http://guides.rubyonrails.org/active_record_querying.html#eager-loading-associations

class User
has_many :microposts
end
class Micropost
belong_to :user
end
# to get user's post
# for single user
#user.microposts
# for many users
#users.each do |user|
user.microposts.each do |post|
post.post_content
end
end

Your user has many microposts. So do the following on users view page i.e. app/views/Users/index.html.erb
<% #Users.each do |user| %>
id = user.id
last_post = user.microposts.last <!-- This will give you last post created by the user -->
<% end %>

Related

rails association with user and post model?

I am going to do association with user and post model.
I added user_id to post model like this
rails generate migration add_user_id_to_posts
In model
user.rb
has_many :posts
post.rb
belongs_to :user
In post views / it work perfect
<%#posts.each do |post|%>
<%=post.post_name%>
<%=post.user.name.first(20).capitalize, post_path(post.user.id)
<%end%>
In user views /I am getting error
undefined method `post_name' for
#Post::ActiveRecord_Associations_CollectionProxy:0x00007fc9c432bde8
<%#users.each do|user|%>
<%=user.posts.post_name%>
<%=user.name.first(20).capitalize,post_path(user.id)%>
<%end%>
If I want to display like this way what I want to do. Pls need help I am new to rails
I want to add post_id to user model.
The reason you are getting the error is because you're trying to call post_name on a collection of posts that belong to a user. A collection is like an array, so you'll have to iterate through that collection and call post_name on each post.
<% #users.each do |user|%>
<% user.posts.each do |post| %>
<%= post.post_name %>
<% end %>
<%= user.name.first(20).capitalize, post_path(user.id) %>
<% end %>
The reason you're getting a collection of posts is because of your associations. A user has_many posts, which means you are going to get back all the posts that belong to a user. That may mean 0 posts or 10 posts depending on how many times the user has posted.
Because of this, you may want to check if the user has any posts before you iterate through them.
NoMethodError means that method does not exist on that posts. But how and why?
In your first example, post is an object of Post — it must respond_to the method you're calling on it.
To see what methods are available on an object, you can call #methods (which is also available on the class-level):
puts post.methods
That will give you an array of the methods you can call on post.
There is also a method called #class we can call to see what class an object is:
puts user.posts.class
Which will return ActiveRecord::Relation which acts like an array under the hood. Because a User has many Post, we have an array of Post, thus calling name on an array of Post objects will not work.
If you want the first name of the posts that a User has:
user.posts.first.name
But beware, because a user may not have any posts.

How do I create a schema for a blog where posts belong to categories (e.g. Music, Anime, Products) & relate to different tables based on category?

I'm working on a Rails app and have made some initial migrations and associations. Here's the schema I currently have:
Current Schema
Right now, I'm not sure if this schema will actually work. I'm trying to include different data in my posts depending on the category (e.g. If the post is in the "Music" category, it will show the title of the record, along with the artists who created it). The way I have it now, some of the tables will have a hardcoded category_id (e.g. products, episodes, records).
If you're trying to include some data of a music record in your post that means that you need to create a relationships between the two tables. for example:
rails g migration add_record_references_to_posts record:references
then rake db:migrate
models/post.rb:
belongs_to :record
validates :band_type, presence: true, if: 'category.id == 2'
models/record.rb:
has_many :posts
This way you can choose from what record your post belongs to using a select (don't forget to add that in your form).
You will then be able to retrieve your record title from your post for example in your post show page you can do:
<% if #post.category.name == "Music" %>
<%= #post.record.title %>
<%= #post.record.name %>
<% end %>
In your post form you can use jquery to show or hide the inputs specific to the post category.
I however don't think that you need the category table at all. You'll be able to know what kind of post it is depending on the presence of the post relationship with other tables (records, episodes or products). For example if the post (the object not the model) belongs to a product, you will know that it's a product's post, so you can do for example:
<% if #post.record.present? %>
<%= #post.record.title %>
<%= #post.record.name %>
<% end %>

populate object_id fields in rails query

I have two models. One named user, and one named orders. Users have an order_id field with the order's id. I have set up orders to belong to users and users to have many orders.
Now I would like to have a view where I show some users, and each order for that user. Obviously it would be nice if I could just get one bit object that has the users and instead of the order_id, have the actual order. I know there are some languages where you can something like this:
found_user.populate(order_id)
Is there an option to do this in rails? I have seen the select function, but it doesn't seem to work, not with User.find() anyhow, which is what I am using.
Any ideas?
When you say order belongs to user, you should have user_id in orders table but not order_id in users table.
Now I would like to have a view where I show some users, and each
order for that user.
And now in the view where you want to display the users and their orders, try the below code
<% #users.each do |user| %>
<%= user.name %> #assuming you have name field in users table.
<% user.orders.each do |order| %>
<%= order.name %> #assuming you have name field in orders table.
<% end %>
<% end %>
Where #users = User.all which is defined in the respected controller action.

Creating a feed with acts_as_taggable_on in Rails

I'm trying to create a feed in Rails utilizing acts_as_taggable_on and I'm having a bit of trouble.
In my app there are Users who belong to Groups and every User selects several Tags for himself/herself using the acts_as_taggable_on context :user_tags. The Users create Posts which also have Tags, but of the context :post_tags.
What I'm trying to do is create a feed for the current User comprised of Posts from within his/her Group that have at least one :post_tag in common with the current User's :user_tags. So for example, if I have a User that chooses "Developer, Designer" as two :user_tags, I'd want to return all Posts from within his/her Group that have "Developer" and/or "Designer" as :post_tags.
After hours of fiddling around, here's what I tried in post.rb, but it gave me an error ("ERROR: column 'tag_id' does not exist LINE 1"), which seems odd given that tag_ids do exist for taggings.
# Returns posts with tags also attributed to the given user.
def self.from_posts_matching_tags_of(user)
matching_tag_ids = "SELECT tag_id FROM taggings
WHERE taggable_id = :user_id"
where("tag_id IN (#{matching_tag_ids}) OR user_id = :user_id", user_id: user)
end
Any suggestions for how to properly create such a feed method would be much appreciated. And if there's any other relevant code you want me to share, just let me know.
So, I figured out a solution that has worked thus far in my (admittedly limited) testing. Hope this is helpful to anyone else seeking to do something similar. Of course, if anybody knows a more efficient way to tackle this, I'm always open to improvements.
I added this to pages_controller.rb and it seems to do the trick:
def index
if logged_in?
#feed_items = Post.tagged_with([#current_user.user_tag_list], :on => :post_tags, :any => true)
end
end
And this on index.html.erb:
<% if #feed_items.any? %>
<% #feed_items.each do |post| %>
<%= link_to post.content, post %><br/>
<% end %>
<% end %>

Searching within an associated array in ruby - rails 3

So lets say we have a Post model, a User model and a View model.
When a user views a post, a new record is created in the Views table. The table links the user, the post, and the current time. Later if that user goes back to view the post again, the record is updated with a new time. Pretty basic stuff.
Posts has_many views, and Users has_many views
Views belongs to Posts and Users
In the index view of the Posts, I want to call the specific view for each post i.e.
<% #Posts.each do |post| %>
<%= post.name %><br/>
<%= post.views %> # This connects all of the views related to this post.
# How do I get the only one connected to this post and the current_user.id?
<% end %>
I feel like theres some simple way of accomplishing this that I'm totally forgetting
You could do something like
current_user.views.where(:post_id => post.id)
# this may work, not sure
current_user.views.where(:post => post)
or
post.views.where(:user_id => current_user.id)
# this may work, not sure
post.views.where(:user => current_user)

Resources