Rails makevoteable help creating user voting link and custom error message - ruby-on-rails

I am having that problem with the gem makevoteable that when the page is loaded the post gets upvoted automatic. Instead of just having a link the user can click and upvote. When the page is reloaded I get the AlreadyVotedError in view. I would prefer a more user friendly error message as "You already voted this post"
My view:
<% #posts.each do |post| %>
<h1><%= post.titel %></h1>
<p><%= post.body_html %></p>
<p><%= link_to 'asdasdasd', current_user.up_vote(post) %>
<% end %>
UPDATE:
My route.rb: match 'stem_op/:id' => 'posts#vote_up', :as => 'stem_op'
My public controller:
def vote_up
#post = Post.find(params[:id])
current_user.up_vote(#post)
flash[:message] = 'Thanks for voting!'
redirect_to post_path(#post)
rescue MakeVoteable::Exceptions::AlreadyVotedError
flash[:error] = 'Already voted!'
redirect_to post_path(#post)
end
My view:
<% #posts.each do |post| %>
<h1><%= post.titel %></h1>
<p><%= post.body_html %></p>
<p><%= link_to 'Stem op', stem_op_path(post.id) %>
</tr>
<% end %>
When I try to vote_up a post I get this error:
Template missing - Do I really need a blank view file?
UPDATE:
def vote_up
#post = Post.find(params[:id])
current_user.up_vote(#post)
flash[:message] = 'Thanks for voting!'
redirect_to post_path(#post)
rescue MakeVoteable::Exceptions::AlreadyVotedError
flash[:error] = 'Already voted!'
redirect_to post_path(#post)
end
Error:
SyntaxError in PostsController#vote_up
C:/Rails/den/app/controllers/posts_controller.rb:103: syntax error, unexpected keyword_end, expecting $end

Yes, current_user.up_vote(post) adds a vote for that user. You need to create a controller action that executes current_user.up_vote(post) and handles the flash message. Then you can link to that action in your view.
Edit to answer comment:
guides.rubyonrails.org/action_controller_overview
In your posts controller I imagine you would want something like:
def upvote
#post = Post.find params[:id]
current_user.upvote(#post)
flash[:message] = 'Thanks for voting!'
redirect_to post_path(#post)
rescue MakeVoteable::Exceptions::AlreadyVotedError
flash[:error] = 'Already voted!'
redirect_to post_path(#post)
end
and in your routes something like:
map.resource :post do
member do
post :upvote
end
end
Your link would become link_to 'Upvote!', upvote_post_url(post), :method => :post

Related

Flash messages only show after redirecting twice

flash[:errors] does not show after redirect_to in create method. But if I send another invalid form it shows up on the second and all following redirects. The same goes for flash[:success] when there are no errors.
I've tried using flash.keep in both this and the route I am redirecting to, and the views work since the messages do appear after multiple redirects. I'm wondering if it is because the redirects are to routes that render too?
In Controller:
def create
user = User.create(user_params)
if user.errors.any?
flash[:errors] = user.errors.full_messages
redirect_back(fallback_location: root_path)
else
flash[:success] = "USER SUCCESSFULLY CREATED"
redirect_to root_path
end
end
In Views:
<% if flash[:errors] %>
<% flash[:errors].each do |error| %>
<p style="color:red;"><%= error %></p>
<% end %>
<% end %>
AND:
<% if flash[:success] %>
<p style="color: red;"><%= flash[:success] %></p>
<% end %>
No flash messages are shown after the first redirect. After or more redirects, the flash messages are shown

Rails: ActionController::InvalidAuthenticityToken

I'm currently working on a project involving users, likes, and posts. I have a like/unlike button that I finally got to work some of the time, but on certain user's profiles when I go to unlike a post, I get thrown this error, which says that it is coming from my destroy action in my likes controller:
ActionController::InvalidAuthenticityToken
I'm using devise, but don't know if that has to do with the cause of the issue.
Right now this is what I'm working with:
<h4>All of <%= #user.email %>'s posts:</h4>
<% #user.posts.order('created_at DESC').each do |post| %>
<li><%= post.content %></li>
<% unless current_user.likes.pluck(:post_id).include?(post.id) %>
<%= form_tag likes_path do %>
<%= hidden_field_tag 'post_id', post.id %>
<%= submit_tag "Like", :class => "like_button" %>
<% end %>
<% else %>
<% like = post.likes.where(user_id: current_user.id).first %>
<div class="unlike_button">
<%= form_tag like_path(like) do %>
<%= hidden_field_tag 'post_id', post.id %>
<%= button_to "Unlike", like_path(post), method: :delete %>
</div>
<% end %>
class LikesController < ApplicationController
def create
#post = Post.find(params[:post_id])
#like = Like.new(user_id: current_user.id, post_id: #post.id)
if #like.save
flash[:success] = "Post Liked!"
redirect_back(fallback_location: root_path)
else
flash[:notice] = "Couldn't like post"
redirect_back(fallback_location: root_path)
end
end
def destroy
#like = Like.find(params[:id])
#like.destroy
flash[:success] = "Post unliked"
redirect_back(fallback_location: root_path)
end
end
class PostsController < ApplicationController
def index
#posts = Post.all
#user = User.find(params[:user_id])
end
def new
#post = Post.new
#user = User.find(params[:user_id])
end
def create
#post = current_user.posts.build(post_params)
if #post.save
flash[:success] = "Posted!"
redirect_to user_path(current_user)
else
flash[:notice] = "Post could not be submitted"
redirect_to users_path
end
end
private
def post_params
params.require(:post).permit(:content)
end
end
There is a comment in application_controller.rb..
# Prevent CSRF attacks by raising an exception.
# For APIs, you may want to use :null_session instead.
so ,you may try changing..
protect_from_forgery with: :exception
to this
protect_from_forgery with: :null_session
Hope it helps :)
I think I have figured it out.. At least have gotten it to work. I wasusing a form_for helper as well as button_to helper. I deleted the form_for helper and just stuck with
<%= button_to "Unlike", like_path(like), method: :delete %>
and it is now working
What helps me solve this problem is adding the Forward Slash in the URL
From:
= bootstrap_form_tag url: 'signup_with_phone' do |form|
To:
= bootstrap_form_tag url: '/signup_with_phone' do |form|

ActiveRecord::RecordNotFound in CommentsController#destroy

I am getting this error while i am going to delete a comment associated with a post.
// my CommentsController
def destroy
#post = Post.find(params[:post_id])
#comments = #post.comments.find(params[:comment])
#comments.destroy
redirect_to post_path(#post)
end
// my form::
<p>
<strong><%= comment.commenter %>: </strong>
<%= comment.body %>
<strong> at </strong><%= comment.created_at %>
<%= link_to 'Delete Comments', [comment.post,comment], method: :delete, data: {confirm: 'Are you Sure'} %>
</p>
I am getting the error in ::
#comments = #post.comments.find(params[:comment])
please tell me where i am wrong..
You probably should have:
#comment = #post.comments.find(params[:id])
#comment.destroy
Since by default, nested resource record id is referenced by params[:id] in destroy action.
Use this instead
#post = Post.where(:id => params[:post_id]).first
unless #post.blank?
#comment = #post.comments.where(:id => params[:id]).first
unless #comment.blank?
#comment.destroy
flash[:notice] = "Comment deleted"
redirect_to post_path(#post)
else
flash[:notice] = "Comment not found"
redirect_to post_path(#post)
end
end
The difference between find and where is that, where returns an empty array if no comment is found. But find raise an ActiveRecord::RecordNotFound error. Is it clear? If no comment of that id is present in the table then it will return an empty array, and in second line I have added a condition that if comment is not found don't perform destroy action. I've simply handled the error.
You have to include <%= flash[:notice] %> in view file to see the error/success message

Ruby on Rails - show_user_path NoMethodError in Users#show

I am a begginer in Rails, im following code from a book and i am trying stuff to see if it breaks/works, anyway heres my UserControllers classUserController
class UsersController < ApplicationController
def new
#user = User.new
end
def edit
#user = User.find(params[:id])
end
def show
#user = User.find(params[:id])
end
def create
#user = User.new(params[:user])
if #user.save
redirect_to #user, :notice => 'Cadastro realizado'
else
render :new
end
end
end
And heres my show.html.erb
<p id="notice"><%=notice%></p>
<h2>Perfil: <%=#user.full_name %></h2>
<ul>
<li>Localização: <%= #user.location %> </li>
<li>Bio: <%= #user.bio %></li>
</ul>
<%= link_to 'Editar Perfil', edit_user_path(#user) %>
<%= link_to 'Mostrar Perfil', show_user_path(#user) %>
My problem is in the last line, when i try to acess this page i get a NomethodError,i am trying to understand why, why can i just change that to #user and the page works?
Try:
<%= link_to 'Mostrar Perfil', user_path(#user) %>
or even just
<%= link_to 'Mostrar Perfil', #user %>
In order to see how to name the routes, open a console and run
rake routes

Nested Resource Sad Path Renders blank comment

I have a comment resource nested in a post resource.
def create
#post = Post.find(params[:post_id])
#comment = #post.comments.build(params[:comment])
#comment.ip = request.remote_ip
if #comment.save
redirect_to post_path(#post, notice: "Comment was successfully created")
else
flash[:alert] = "Comment could not be created"
render 'posts/show'
end
end
This all works well enough, but I have a nag item in that when the posts/show page with the comment form re-renders, it shows the comment that didn't pass validation inline. I'd like to know the correct way to do this, short of performing some logic in the view layer to not display a comment that isn't saved.
I ended up solving it in the view, because I couldn't find any other solution
<% #post.comments.each do |c| %>
<% unless c.new_record? %>
<strong><%= "#{c.name} wrote: " %></strong><br />
<blockquote><%= c.body %></blockquote>
<% end %>
<% end %>

Resources