Showing username with association with Rails - ruby-on-rails

I've been researching but cannot seem to find the answer. All I am looking to do is setup an association for users and articles (the most basic setup =P). Anyway, I setup the has_many and belongs_to in the models, added the user_id to the article model. Within my create action, I added a variable to save the current_user and then I am able to have that appear within the show page. Problem is I cannot have the username appear within the index page (in my situation, it is called community). Here are the various codes:
Article.rb (Model):
class Article < ActiveRecord::Base
belongs_to :user
...
User.rb (Model):
class User < ActiveRecord::Base
has_many :articles
...
articles_controller:
def create
#article = Article.create(article_params)
#article.user = current_user
if #article.save
flash.notice = "Article #{#article.title} has created!"
redirect_to community_path
else
flash.notice = "Try Again!"
end
end
Show View:
....
<p><%= #article.user.first_name %> <%= #article.user.last_name %></p>
....
Community(Index) View:
<div class="center_com_col col">
<div class="main_community">
<% #articles.each do |x| %>
<ul>
<li>
<h2><%= link_to article_path(x) do %><%= x.title %><% end %><br>
<p>
<%= Code to go here for user =><br>
Written on: <%= x.created_at.strftime("%B %d, %Y") %>
</p>
</h2>
</li>
<li>
<p><%= truncate simple_format(x.body), length: 250, escape: false %> (<%= link_to "read more", article_path(x) %>)</p>
</li>
</ul>
<% end %>
</div>
Everything seems to work well but I am clueless when it comes to that community (index) page since I am iterating through the articles.
Thank you very much for any help you may have!
EDIT: Here are my show and community controllers:
def community
#articles = Article.all.order("created_at DESC").limit(5)
#users = User.all.order("created_at DESC")
render :layout => 'community_layout'
end
def show
#article = Article.friendly.find(params[:id])
#users = User.all.order("created_at DESC")
render :layout => 'community_layout'
end
Joe

I agree with BroiSatse.
Following some best practices would prevent these errors:
Don't use x as the variable name unless referring to x position!
Always do if #articles.any? before you begin an each if there are no
articles that will cause an error like Nil class Nil!
Before you use art.user have an if art.user exists.
Here Should be the code:
<ul> <!--The UL should not be part of your each loop. -->
<% if #articles.any? %>
<% #articles.each do |art| %>
<li>
<h2><%= link_to article_path(art) do %><%= art.title %><% end %><br>
<p>
<% if art.user %>
<%= art.user.first_name %> <%= art.user.last_name %><br>
<$ end %></h2>
<%= time_ago_in_words(art.created_at) %>
</p>
</li>
<li>
<p>
<%= truncate simple_format(x.body), length: 250, escape: false %> (<%= link_to "read more", article_path(x) %>)
</p>
</li>
<% end %> <!--end refers to #articles.each -->
</ul>
<% end %>
<!--end refers to #articles.any? -->
I believe that some of your articles may not have been created with users authoring them ensure that your
db/seeds.rb:
user = User.create(email: "email#gmail.com", first_name: Faker.first_name, last_name: Faker.last_name)
user.articles.create(title: "ARTICLEs are awesome man!", body: 'Yes in a shocking report people are reading articles")
Also to test specifically do:
rails c
to enter rails console.
articles = Article.all
articles.each { |art| print art.user } => I am guessing you'll get nilClass Nil!

Related

How to pass more than one parameters to render in rails?

Below is my review.html.erb:
<% provide(:title, 'All reviews') %>
<h1>All reviews</h1>
<ol class="reviews">
<%= render #reviews %>
</ol>
<%= will_paginate #reviews %>
And my _review.html.erb looks like:
<li>
<p>Student: <%= Student.find(review.student_id).name%></p>
<p>Score: <%= review.score%></p>
<p>Review: <%= review.review%></p>
<p>Created at: <%= review.created_at%></p>
</li>
How can I pass #students as well to render for example?
I tried <%= render #reviews, #students %> in review.html.erb and Student: <%= student.name%> in _review.html.erb. It didn't work.
You don't actually need to pass multiple parameters. You just need to setup the assocations between reviews and students:
class Student < ApplicationRecord
has_many :reviews
end
class Review < ApplicationRecord
belongs_to :student
# optional but avoids a law of demeter violation
delegate :name, to: :student, prefix: true
end
<li>
<p>Student: <%= review.student_name %></p>
<p>Score: <%= review.score %></p>
<p>Review: <%= review.review %></p>
<p>Created at: <%= review.created_at %></p>
</li>
To avoid a N+1 query issue you should use includes or eager_load to load the student with the reviews:
#reviews = Review.includes(:student)
.all
If you do actually want to pass additional arguments when rendering a collection (which isn't needed here) you do it with local assigns:
<%= render #reviews, locals: { foo: 'bar' } %>
This will be available in the partial as foo or local_assigns(:foo).
Reivew table and students are related
In _review.html.erb , you don't need use Student.find(review.student_id)
<li>
<p>Student: <%= review.student&.name%></p> // changed
....
</li>

Acts_As_Votable Gem Automatically Liking Everything

I'm using the acts_as_votable gem to like and unlike "Deals" in my Ruby on Rails project. My user is set to act_as_voter and my deal is set to acts_as_votable, but for some reason everything is set to like as soon as a new user is created, and they can't unlike the deal. For some reason my list of deals all have an unlike button and it doesn't actually do anything but refresh the page. Here's some of my code.
app/views/catalog/index.html.erb
<ul class="deals_list">
<% #deals.each do |deal| %>
<li>
<div>
...
<div class="favorite">
<% if account_signed_in? and current_account.accountable_type == "Personnel" %>
<%= image_tag("dark-favorite.png") %>
<% if deal.liked_by current_account %>
<%= link_to unlike_deal_path(deal), method: :put do %>
Unlike
<% end %>
<% else %>
<%= link_to like_deal_path(deal), method: :put do %>
Like
<% end %>
<% end %>
<% end %>
</div>
</li>
<% end %>
</ul>
app/controllers/deals_controller.rb
def like
#deal = Deal.find(params[:id])
#deal.liked_by current_account
redirect_back(fallback_location: catalog_index_url)
end
def unlike
#deal = Deal.find(params[:id])
#deal.unliked_by current_account
redirect_back(fallback_location: catalog_index_url)
end
config/routes.rb
resources :deals do
member do
put 'like', to: "deals#like"
put 'unlike', to: "deals#unlike"
end
end
Be sure and read the entire Readme because you're using the library wrong.
To check if a voter has voted on a model, you can use voted_for?. You can check how the voter voted by using voted_as_when_voted_for.
I zeroed in on your problem because I was expecting to see a "?" after the deal.liked_by call, which would indicate a boolean result (by convention, not always the case).
So use this instead:
<% if current_account.voted_for? deal %>

Error with instance variable in Index view

So in my tutors_controller.rb this is my index action
def index
#tutor = Tutor.all
#tutor = #tutor.fees_search(params[:fees_search]) if params[:fees_search].present?
end
and in my index.html.erb this is the view
<div class='container'>
<%= form_tag(tutors_path, method: :get) do %>
<%= label_tag 'fees_search', 'Max Fees' %>
<%= select_tag 'fees_search', options_for_select((10..50).step(10)) %>
<%= submit_tag 'Filter' %>
<% end %>
<% #tutor.each do |tutor| %>
<% unless tutor.admin? %>
<div class='row' id='tutor-listing'>
<div class='col-xs-4'>
<%= image_tag(tutor.profile.avatar.url, :class => "img-rounded" ) if tutor.profile.avatar? %>
</div>
<div class='col-xs-8'>
<h3><%= link_to tutor.full_name, tutor_path(tutor) %></h3>
<% unless tutor.subjects.nil? %>
<% tutor.subjects.each do |subs| %>
<span class='badge'id='tutor-listing-badge'>
<%= link_to subs.name, subject_path(subs) %>
</span>
<% end %>
<% end %>
<% unless current_tutor %>
<%= button_to "Shortlist Tutor", add_to_cart_path(tutor.id), :method => :post %>
<% end %>
</div>
</div>
<% end %>
<% end %>
</div>
So i understand that when the index view first renders, #tutor would simply be Tutor.all so it renders each individual tutor perfectly.
After trying to filter it though, i start receiving errors. The exact error is NoMethodError in Tutors#indexand the highlighted line is <% unless tutor.admin? %>
profile.rb model
class Profile < ActiveRecord::Base
belongs_to :tutor
scope :fees_to, -> (fees_to) { where("fees_to <= ?", "#{fees_to}") }
end
tutor.rb model
class Tutor < ActiveRecord::Base
has_one :profile, dependent: :destroy
def self.fees_search(n)
#profile = Profile.fees_to(n)
if #profile.empty?
return Tutor.none
else
#profile.each do |y|
y.tutor
end
end
end
end
I get that now my #tutor instance variable has obviously changed. But how do i go about resolving this problem? Should i be rendering a partial instead? Obviously my index action in my controller could be "better" also but i'm quite confused now as to what i should be doing.
Would appreciate any advice! Thank you!
#profile.each do |y|
y.tutor
end
Seems to be a problem. All the other outcomes are a Tutor.something scope, whereas this will return the last tutor only. Change each to map to get an array of Tutors instead.

Need to group shows by day in a rails Application

I am trying to get shows on a certain day to show up just for that day and I would like to be able to see what shows are going on in the next couple of days as well.
The View:
<% t = Time.new %>
<h2 class="center" style="color:#2A2C2B"><u><%= t.strftime("%A, %B %e") %></u></h2>
<% #clubs.each do |club| %>
<!-- # <% club.shows.future.present? %> -->
<h1 class="club"><%= link_to club.name, club.website %> </h1>
<% club.shows.future.each do |show| %>
<h3 class="center"><%= show.pretty_start_time %></h3>
<% show.comedians.each do |comedian| %>
<div>
<ol>
<h4 class="comedian"><%= link_to simple_format(comedian.name),comedian_path(comedian) %></h4>
<p class="bio"><u><%= comedian.bio %></u></p>
</ol>
</div>
<% end %>
<% end %>
<%- end -%>
The Comedy Hub Controller:
class ComedyHubsController < ApplicationController
def show
#clubs = ComedyClub.all
end
end
This might work:
<% shows.goup_by{|show| show.date}.each do |dategroup| %>
<# do something to indicated the group up here? %>
<%= dategroup.each do |show| %>
<li> <%# put details here %> </li>
<% end %>
<% end %>
Assuming, there is a DateTime column on Show called start and the ComedyClub model has a a has_many :shows and the Show model has the belongs_to :comedy_club association defined
In your ComedayHubsController#show method, do the following query
#clubs = ComedyClub.join(:shows).where("shows.start >=?", DateTime.now).order("shows.start ASC")
Now only clubs with shows in the future will be sent to the view and already ordered by start.

Rails 3 - Why is my Post#Show view showing all of its comments' database data in one big block after the comments list?

In a Rails 3 blog type of app, I have a polymorphic comments model, with Posts having Comments (through :commentable). The Post#Show page has a form for comments that post through AJAX to a comment list below. Everything is working fine EXCEPT that Rails is for some reason dumping a full list of the database entries for all comments on that post in []'s at the very bottom of my comments list. I can't figure out where this is coming from and why!
Here are maybe the relevant code chunks, please feel free to request more! Thanks in advance.
views/posts/show
...
<%= render 'comments' %>
...
views/posts/_comments
<%= render :partial => 'comments/form' %>
<ul class="comments">
<% if #post.comments.empty? %>
<li>none yet</li>
<% else %>
<%= render :partial => 'comments/comment' %>
<% end %>
</ul>
views/comments/comment
<%= #comments.each do |comment| %>
<li>
<p class="comment_body">"<%= comment.body %>"</p>
<br/>
<p class="comment_info"><%= comment.name %> - <%= time_ago_in_words(comment.created_at) %> ago </p>
</li>
<% end %>
posts controller
def show
#post = Post.find(params[:id])
#comments = #post.comments
#commentable = #post
#comment = Comment.new(:commentable => #post)
#title = #post.author
end
And here's where the error creeps in (from Page Source). Right after the last comment closes and before the comments closes:
....
</li>
[#<Comment id: 97, name: "hmmm?", body: "hmmm", created_a...
</ul>
What is that thing and why is it here!? Thanks.
it's the = in the #comments.each tag. It is returning the result of each, which is the whole array.
For example:
irb> [1,2].each {|i| puts i }
1
2
=> [1, 2]
So:
<%= #comments.each do |comment| %>
Should simply be:
<% #comments.each do |comment| %>

Resources