List only the last 5 articles seen by current user? - ruby-on-rails

I am following this stackoverflow post, How can i store and show only the last 5 NEWS seen by the current user?
However, i think I am getting this error (Couldn't find Article with 'id'=python-0), because I'm using friendly_id gem to generate the article url. Is there a workaround for this?
Application controller
before_action :recently_viewed_articles
def recently_viewed_articles
session[:article_id] ||= []
session[:article_id] << params[:id] unless params[:id].nil?
session[:article_id].delete_at(0) if session[:article_id].size >= 5
end
Pages Controller
def home
#recent_articles = session[:article_id]
#feed = current_user.feed
end
_feed.html.erb
<div class = "container">
<div class = "row">
<div class = "col-md-9">
<%= render #feed %>
</div>
<div class = "col-md-3">
<div class="list-group">
<button type="button" class="list-group-item list-group-item-action active">
Recently visited
</button>
<% #recent_articles.each do |recent| %>
<button type="button" class="list-group-item list-group-item-action">
<%= link_to "#{Article.find(recent).title}", article_path(Article.find(recent)) %>
</button>
<% end %>
</div>
</div>
</div>
</div>

As per documentation, I believe you should be using friendly scope.
Article.friendly.find(recent)

https://github.com/norman/friendly_id
Have you set everything up as you should do? If you haven't, then you can use:
Article.friendly.find('python-0')
Otherwise, in your article model:
friendly_id :title, use: [:slugged, :finders]
Then you can call
Article.find('python-0')

Related

Strange Things - Ruby on Rails 5

Hey guys I'm trying to catch all my categories descriptions inside my Category model and show them at my shop index page. So far everything working fine. All categories came perfectly at screen but just below then rails shows all categories as an array.
This is my Category controller
class Site::HomeController < ApplicationController
def index
#categories = Category.all
end
end
This is my index page
`
<div class="row">
<div class="col-lg-3">
<h1 class="my-4">Shop Name</h1>
<div class="list-group">
<%= #categories.each do |cat| %>
<%= cat.description %>
<% end %>
</div>
</div>`
and below you can check the issue
I appreciate for some help.
regards
Try this:
<% #categories.each do |cat| %> #remove "="
<%= cat.description %>
<% end %>

Show only names that belong to a code

So in my app a guest searches for their RSVP code in the code/index.html page then clicks on a continue link that brings them to the rsvp page. I am trying to show only names that belong to the specific code on the RSVP but currently all names are showing up. I have passed the code as a param in the link on the index page but when I get to the rsvp page it is showing up in the url with a period which doesn't seem right ex: /rsvp.1
so I am guessing that this is where I am going wrong but I cant figure out why:
associations
Guest belongs_to :code
Code has_many :guest
code/index.html.erb
(page with the link that takes user to rsvp page and passes the params to rsvp page)
<h2><%= link_to 'Continue', rsvp_path(code) %></h2>
code_controller
def index
#codes = Code.search(params[:search])
end
def rsvp
code_id = params[:code]
#guests = Guest.where("code_id", "#{code_id}")
end
code/rsvp.html.erb
<div class="row">
<div class="box">
<div class="col-lg-12">
<form class="row form-inline">
<% #guests.each do |guest| %>
<%= guest.name %>
<% end %>
<div class="form-group">
<p> Will you be attending the wedding of Kristen Albrecht and Chris Alford September 1, 2017? </p>
<button aria-haspopup="true" class="btn btn-default dropdown-toggle" ngbdropdowntoggle="" type="button" aria-expanded="false">
Yes</button>
</div>
<div class="form-group">
<button type="submit" class="btn btn-primary">No</button>
</div>
</form>
</div>
</div>
</div>
routes
resources :codes
resources :guests
get '/code' =>'codes#code'
get '/rsvp' =>'codes#rsvp'
To make sure that code is a parameter in the URL, you have to make the following changes:
routes.rb
get '/rsvp/:code' =>'codes#rsvp'
code/index.html.erb
<h2><%= link_to 'Continue', rsvp_path(code: code) %></h2>
This way params[:code] will have a value in the code_controller
Okay I figured it out:
I changed the link on the index page to
<%= link_to "Continue", {:controller => "codes", :action => "rsvp", :code_id => code.id }%>
then I changed the controller code to
def rsvp
#guests = Guest.where(code_id: params[:code_id])
end

Rails: Adding a "latest post" to blog

Adding a "latest post" section to blog
This is my original code to show all my posts and it works great.
<% #post.each do |post| %>
<div class="col-md-4 col-sm-6 portfolio-item">
<a href="#portfolioModal6" class="portfolio-link" data-toggle="modal">
<div class="portfolio-caption">
<h4><%= link_to post.title, post %></h4>
<p class="text-muted"><%= post.created_at.strftime("%B, %d, %Y") %></p>
</div>
</a>
</div>
<% end %>
However, I also want to add a large div that shows my latest post. So I copy/paste the code above and changed the line <% #post.each do |post| %>to the following:
<% #post = Post.last do |post| %>
There was no errors, but nothing showed up either. The reason I added this code is because I saw in a tutorial where the teacher went into rails c and typed #post = Post.last and could see the last post created. However, when I go into terminal and type it, I get the error:
No command '#post' found, did you mean:
Command 'mpost' from package 'texlive-binaries' (main)
Command 'rpost' from package 'suck' (universe)
#post: command not found
You shouldn't type it on your terminal, but in the rails console. On your terminal, type rails console, when that loads up, you can then do:
post = Post.last
In order to only render for the last post, you wouldn't need the block, as such:
<% post = Post.last %>
<div class="col-md-4 col-sm-6 portfolio-item">
<a href="#portfolioModal6" class="portfolio-link" data-toggle="modal">
<div class="portfolio-caption">
<h4><%= link_to post.title, post %></h4>
<p class="text-muted"><%= post.created_at.strftime("%B, %d, %Y") %></p>
</div>
</a>
</div>
By the way, it's not best practice to handle domain objects in your view. You could have this as an instance variable in your controller, as a Facade object if you have multiple objects.
Extending #oreoluwa's answer with a little more rails conventions:
Your post object:
class Post < ActiverRecord::Base
scope :ordered, -> { order(created_at: :desc) } # or use your own column to order
end
Your Controller (where your view is where the last post should be rendered). You should not make queries in your views to keep better a better control.
class ExamplesController < ApplicationController
def show
#latest_post = Post.ordered.first
end
end
Your View
<div class="col-md-4 col-sm-6 portfolio-item">
<a href="#portfolioModal6" class="portfolio-link" data-toggle="modal">
<div class="portfolio-caption">
<h4><%= link_to #latest_post.title, #latest_post %></h4>
<p class="text-muted"><%= #latest_post.created_at.strftime("%B, %d, %Y") %></p>
</div>
</a>
</div>

Rails 4 - Messenger gem - tutorial setup

I am trying to make an app in Rails 4.
I'm trying to follow this tutorial to setup the messenger gem. http://josephndungu.com/tutorials/private-inbox-system-in-rails-with-mailboxer
I have:
Gemfile:
gem "mailboxer"
User.rb
def mailboxer_name
self.full_name
end
def mailboxer_email(object)
self.email
end
mailboxer.rb initialiser
config.email_method = :mailboxer_email
config.name_method = :full_name
I have an attribute in my user table called :email and I have a method in my user model called:
def full_name
if first_name.present?
[*first_name.capitalize, last_name.capitalize].join(" ")
else
test full name
end
end
One difference between this attempt and the tutorial is that since I previously tried the site point tutorial (and couldn't get it working), I already have a messages controller and view folder in my app. Where this tutorial users 'mailbox', I use 'messages'
I can't get past the first test point in this tutorial. I get this error:
NoMethodError in MessagesController#inbox
undefined method `inbox' for #<ActiveRecord::Associations::CollectionProxy []>
The error message highlights this method:
def inbox
#inbox = messages.inbox
#active = :inbox
end
I have:
messages controller
class MessagesController < ApplicationController
before_action :authenticate_user!
def inbox
#inbox = messages.inbox
#active = :inbox
end
def sent
#sent = messages.sentbox
#active = :sent
end
def trash
#trash = messages.trash
#active = :trash
end
end
application helper
def flash_class(level)
case level.to_sym
when :notice then "alert alert-success"
when :info then "alert alert-info"
when :alert then "alert alert-danger"
when :warning then "alert alert-warning"
end
end
def active_page(active_page)
#active == active_page ? "active" : ""
end
messages helper
def unread_messages_count
# how to get the number of unread messages for the current user
# using mailboxer
messages.inbox(:unread => true).count(:id, :distinct => true)
end
messages views folder has:
_folder_view.html.erb
<div class="row">
<div class="spacer"></div>
<div class="col-md-12">
<!-- we'll configure this to compose new conversations later -->
<%= link_to "Compose", "#", class: "btn btn-success" %>
<div class="spacer"></div>
</div>
<div class="col-md-4">
<div class="panel panel-default">
<div class="panel-body">
<%= render 'messages/folders' %>
</div>
</div>
</div>
<div class="col-md-8">
<div class="panel panel-default">
<div class="panel-body">
<!-- individual conversations will show here -->
</div>
</div>
</div>
</div>
view raw
_folders.html.erb
<ul class="nav nav-pills nav-stacked">
<li class="<%= active_page(:inbox) %>">
<%= link_to messages_inbox_path do %>
<span class="label label-danger pull-right"><%=unread_messages_count%></span>
<em class="fa fa-inbox fa-lg"></em>
<span>Inbox</span>
<% end %>
</li>
<li class="<%= active_page(:sent) %>">
<%= link_to messages_sent_path do %>
<em class="fa fa-paper-plane-o fa-lg"></em>
<span>Sent</span>
<% end %>
</li>
<li class="<%= active_page(:trash) %>">
<%= link_to messages_trash_path do %>
<em class="fa fa-trash-o fa-lg"></em>
<span>Trash</span>
<% end %>
</li>
</ul>
each of inbox.html.er, sent.html.erb and trash.html.erb
<%= render partial: 'messages/folder_view' %>
routes.rb
get "messages/inbox" => "messages#inbox", as: :messages_inbox
get "messages/sent" => "messages#sent", as: :messages_sent
get "messages/trash" => "messages#trash", as: :messages_trash
Application controller:
helper_method :messages
private
def messages
#messages ||= current_user.messages
end
Can anyone see where I've gone wrong?
I'm up to tutorial step that says: Clicking the inbox link should take you to our up and running inbox page with navigation already in place for the inbox, sent and trash folders.
Instead, I get an error message that says:
NoMethodError in MessagesController#inbox
undefined method `inbox' for #<ActiveRecord::Associations::CollectionProxy []>
Can anyone see what's wrong?
You've forgot to add helper method messages to ApplicationController as it made in tutorial:
class ApplicationController < ActionController::Base
# [...]
helper_method :messages
private
def messages
#messages ||= current_user.mailbox
end
protected
# [...]
end
Update 1
I see that in your helper you have current_user.messages in should be current_user.mailbox

Paginating Tags in Rails 4

I'm using Kaminari to paginate my posts page. A post has many tags and each tag links to a "Show" page that displays all posts with that tag. I'm trying to paginate this tags page but it never quite works.
tags/show
<div class="post-index">
<h1><%= #tag.name %></h1>
<ul>
<% #tag.posts.each do |post| %>
<li>
<div class="post">
<div class="featured-image">
<%= link_to image_tag(post.featured_image.url(:featured)), post_path(post) %>
</div>
<div class="info">
<div class="title">
<h2><%= link_to post.title, post_path(post) %></h2>
</div>
<div class="excerpt">
<p><%= truncate(strip_tags(post.body), length: 360) %></p>
</div>
</div>
</div>
</li>
<% end %>
</ul>
<%= paginate #tags %>
</div>
tag.rb
lass Tag < ActiveRecord::Base
has_many :taggings
has_many :posts, through: :taggings
paginates_per 2
end
tags_controller.rb
class TagsController < ApplicationController
def show
#tag = Tag.find(params[:id]).page(params[:page])
end
end
I've tried all I can think of. The examples Kaminari uses are
tag = Tag.order(:name).page(params[:page])
but this doesn't work and returns a no method "posts" error. I tried paginating the posts model instead but that doesn't work.
If I remove any pagination reference, it displays all the posts correctly on the tag page.
Thanks for any advice
I'm not sure about what do you want to paginate? Tags or posts? In your code, you want to paginate "#tags", but you never define "#tags".
#tag = Tag.find(params[:id])
#posts = #tag.posts.page(params[:page])

Resources