How can I get data from multiple table association in rails? - ruby-on-rails

I want to get data from multiple table in rails,but it is not working.
Here is my code.
Category.rb
has_many :posts
post.rb
has_many :mini_posts
belongs_to :category
mini_post.rb
belongs_to :post
controller
#posts = Category.find(params[:id]).posts.mini_posts
viewfile
<% #posts.each do |post| %>
<%= post.title %>
<%= post.description %>
<% post.mini_posts.each do |mpost| %>
<%= mpost.name %>
<%= mpost.experience %>
<% end %>
<% end %>
The error shows "undefined method `mini_posts'.
How can I solve this?

Your code is chaining methods, and returning mini posts, not eager loading the mini posts which is what I assume you want.
You want either
#posts = Post.includes(:mini_posts).where(category_id: params[:id])
Or
#category = Category.includes(posts: :mini_posts).find(params[:id])
#posts = #category.posts

Change
#posts = Category.find(params[:id]).posts.mini_posts
to
#posts = Category.find(params[:id]).posts

Related

Where's the textNode in the view coming from?

# controller
def index
#teams = TeamMember.where(user: current_user)
end
# view
<%= #teams.each do |t| %>
<h2><%= t.project.name %></h2>
<p>Where's the line below this coming from?</p>
<!-- what's happening here? -->
<% end %>
The result in the browser looks as follows. It returns #projects as a string. Where is this coming from and how do I remove it?
ERB
You trigger ERB by using embeddings such as <% %>, <% -%>, and <%= %>. The <%= %> tag set is used when you want output.
You have used <%= %> for looping projects and the block form of Array#each returns the original Array object, which is why it prints the projects result at the end.
you have to use <% %> for #projects.each do |p| instead of <%= %>
# view
<% #projects.each do |p| %>
<h2><%= p.name %></h2>
<% end %>
Team member Model
class TeamMember < ApplicationRecord
belongs_to :user
belongs_to :project
end
User Model
class User < ApplicationRecord
has_many :team_members
end
Project Model
class Project < ApplicationRecord
has_many :team_members
end
Controller
def index
#teams = current_user.team_members
end
View
<% #teams.each do |t| %> // Remove '=' from the loop itereation
<h2> <%= t.project.name %> </h2>
<% end %>

act_as_followers get all posts of user I'm following

Im trying to get all the Posts from the the Users. I'm following using the act_as_follower gem. The User follows a profile model, and Posts belong to a User.
My User model:
acts_as_follower
My Profile model the user follows:
belongs_to :user
acts_as_followable
Post model:
belongs_to :user
My Post Controller.rb:
def follow
#profile = Profile.find(params[:id])
current_user.follow(#profile)
redirect_to :back
end
def unfollow
#profile = Profile.find(params[:id])
current_user.stop_following(#profile)
redirect_to :back
end
Im trying to implement something like this using follows_by_type method provided:
#posts = current_user.follows_by_type('Post').order("created_at DESC")
But the thing is the User follows the Profile model, but here I'm looking for a type 'Post'.
EDIT
In my index controller i'v set up the following:
#favoritePost = Post.where(user_id: current_user.all_follows.pluck(:id))
And in the view iv implemented this:
<% if user_signed_in? %>
<%#favoritePost.each do |post| %>
<%= post.title %>
<% end %>
<% end %>
The gem lets you follow multiple models and follows_by_type('Post') filters the Posts you follow.
What you're looking to do is to return the posts from the users you follow.
Controller
#posts = Post.where(user_id: current_user.all_following.pluck(:id))
View
<% #posts.each do |post| %>
<%= post.title %>
<% end %>
I worked out this solution, might not be the best, but it works as required.
In my controller i set this up:
#following = current_user.all_following
#followposts = #following.each do |f|
f.user.id
end
And in my view I have set this up:
<% #followposts.each do |f| %>
<% f.user.posts.each do |g| %>
<%= g.title %>
<% end %>
<% end %>

rails rendering index in index with fragment caching

In my rails 4 app I have comments for different models with polymorphic association. For the post model I display comments on the index page, but for product model I do it on the show page. I have problems with fine-tuning the rendering and caching on the post index page, since it's comments index in posts index. I provided my solutions both for the post version and product version.
I don't use touch:true in comment model since it doesn't make sense on the product show page. Thanks to this I don't use caching for the posts on the posts index page since the cache key would be too complex thanks to the comments.
My questions:
Is there a better way to render comments for the posts?
Is my caching strategy good enough or I should use an "outer" caching for product or post?
Post has_many :comments, as: :commentable
Product has_many :comments, as: :commentable
Comment belongs_to :commentable, polymorphic: true ###### NO touch: true
posts index
<%= render #posts %> #no caching here, key would be too complex
_post
<% cache ['post', post, post.user.profile] do %>
<%= post.user.full_name %> #delegated from profile
<%= post.body %>
<% end %>
<%= render partial: 'comments/form', locals: { commentable: post } %>
<%= render partial: 'comments/comment', collection: post.comments.ordered.includes(:user, :user_profile), as: :comment %>
products controller
def show
#product = Product.find(params[:id])
#comments = #product.comments.ordered.includes(:user, :user_profile)
end
products show
<% cache [#product, #product.user.profile] do %>
<%= product.user.full_name %> #delegated from profile
<%= product.name %>
<%= product.description %>
<% end %>
<% cache ['comments-index', #comments.map(&:id), #comments.map(&:updated_at).max,
#comments.map{ |comment| comment.user.profile.updated_at }.max] %>
<%= render #comments %>
<% end %>
_comment (same both for product and post)
<% cache ['comment', comment, comment.user.profile] do %>
<%= comment.user.full_name %> #delegated from profile
<%= comment.body %>
<% end %>

How to show articles with special categories?

So I'm using has_and_belong_to_many association for two models (Article and Category). My header have link with dropdown menu where different categories appears. All my articles are on index page and I need to sort it depending what category it has so users could choose what they want to see. I guess I should do something in show action in category controller, but don't know what exactly. To solve this I played with different each iterations in my views and controller, but unfortunately it didn't help.
Any help will be appreciated
You can select articles with certain category with
selected_articles = Category.find_by_name("Name of category").articles
Or, if you don't know the name simply
selected_articles = Category.find(category_id).articles
Article.joins(:category).where(categories: {id: :your_category_id})
#config/routes.rb
resources :articles do
get ":category_id", action: :index, on: :collection #-> url.com/articles/:category_id
end
#app/controllers/articles_controller.rb
class ArticlesController < ApplicationController
def index
if params[:category_id]
#articles = Article.joins(:categories).where(category: {id: params[:category_id]})
else
#articles = Article.all
end
end
end
This will allow you to use:
#app/views/articles/index.html.erb
<%= form_tag articles_path do %>
<%= f.collection_select :category_id, Category.all, :id, :name %>
<%= f.submit %>
<% end %>
<% #articles.each do |article| %>
<%= article.title %>
<% end %>

has_many and belongs_to nameerror rails

This is my index_controller
def index
#category = Category.all
end
My category model contains
has_many :sub_categories
and my sub_category model contains
belongs_to :category
And here is my view
<% category.sub_categories.each do |f| %>
<li>f.name</li>
<% end %>
I am using rails 4 and am getting error as
undefined local variable or method `category' for #<#<Class:0xab758cc>:0xb56c46d8>
You're just a little bit off with your naming conventions and what sort of code it prompts you to write:
def index
#categories = Category.all
end
#category should be #categories, because Category.all will return an ActiveRecord Relation of 0, 1 or many Category objects, not a single object.
Then:
<% #categories.each do |category| %>
<% category.sub_categories.each do |sub_category| %>
<li><%= sub_category.name %></li>
<% end %>
<% end >
First you iterate over the categories from Category.all, then for each Category, you iterate over its SubCategories.
You have two problems there.
It should be #category, not category
It should be <li><%= f.name %></li>
You missed the reference to the instance variable and the ERB tag to use f.name, it should be
<% #category.sub_categories.each do |f| %>
<li><%= f.name %></li>
<% end %>

Resources