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.
Related
I have a Quiz model that has_many questions. I need to show all the ids of questions associated with a particular Quiz in text_field. At present my code is like this:
<%= text_field(:quiz, :quiz_questions) %>
This displays the object quiz_questions but I must display the ids of all the questions of that quiz. I want something like this:
<%= text_field(:quiz, :quiz_questions, :id) %>
How can I do that?
The second argument quiz_questions is your model method. Therefore you need to add one to your model that only returns the ids
# app/models/quiz.rb
def question_ids
questions.ids
end
in your view
<%= text_field(:quiz, :question_ids) %>
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 %>
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 %>
I am working on an application that involves "follow/unfollow" functionality. Users can follow Objects and Objects can have many Users following them. It's a has_many :through relationship via a Relationships model/controller.
I have the following snippet in the object#show view:
<% if current_user.following?(#object) %>
<%= render 'unfollow' %>
<% else %>
<%= render 'follow' %>
<% end %>
When testing various functionalities in a request spec, it shows undefined method 'following?' for nil:NilClass and fails all of the object#show specs.
The following? method is in the User model and looks like this:
def following?(object)
relationships.find_by_object_id(object.id)
end
The method following? is in the User model (since they are the only ones doing following and unfollowing). I thought you could use methods between objects in Ruby, but perhaps not. If not, how would I go about refactoring this to be able to use that method?
Thanks in advance for any help!
There is no current_user helper in specs. That's why you get nil.
You should stab test user into current_user variable
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)