Rails post delete functionality giving template error - ruby-on-rails

I am trying to have a link to delete a certain reservation from the database. This is my solution but it keeps giving Template Error. It shouldn't render the view but it is.
def delete
#current = Reservations.find(params['reservations']['id'])
respond_to do |format|
if current_user
if #current.user_id == current_user.id
#current.destroy
format.html { redirect_to :back }
else
format.html { redirect_to root_path }
end
else
format.html { redirect_to root_path }
end
end
end
My routes file
post "reservations/delete", to: 'reservations#delete', as: 'delete_reservation'
My view that includes the delete link:
<%= form_for item, :url => {:controller => 'reservations', :action => 'delete'}, :method => 'post' do |f| %>
<%= f.hidden_field :id, :value => item.id %>
<%= f.submit "Delete", :class =>'btn btn-danger btn-small' %>
<% end %>

Related

Rails passing params in link_to how to make it secure

I am trying to create a like and dislike function inside rails for that I am using lin_to helper to pass params but there is an issue when ever someone tries to copy paste the links it updated the database . I am using ajax to make this function work here is the code for my method .
Controller code:
class FeedLikesController < ApplicationController
before_action :authenticate_user! ,only: [:create, :destroy]
before_action :get_feed ,only: [:create, :destroy]
def index
#fees = FeedLike.all
respond_to do |format|
format.html
format.js
end
end
def update
#feed_likes = FeedLike.find_or_create_by(feed_like_params)
respond_to do |format|
if #feed_likes.save
format.html { redirect_to root_url, notice: 'Like ' }
end
end
end
def create
#feed_like_counter = Feed.find(params[:feed_id])
#feed_likes = FeedLike.find_or_create_by(:feed_id => params[:feed_id],:user_id =>params[:user_id])
#f = #feed_like_counter.like_count
#feed_like_counter.like_count = #f+1
#feed_like_counter.save
respond_to do |format|
if #feed_likes.save
format.html { redirect_to root_url, notice: 'Like ' }
format.js
end
end
end
def delete
end
def destroy
#feed_like_counter = Feed.find(params[:feed_id])
#feed_likes = FeedLike.where(feed_like_params)
#f = #feed_like_counter.like_count
#feed_like_counter.like_count = #f-1
#feed_like_counter.save
respond_to do |format|
if #feed_likes.destroy_all
format.html { redirect_to root_url, notice: 'Unlike ' }
format.js
end
end
end
def feed_like_params
params.permit(:user_id, :feed_id)
#params[:market_place]
end
def get_feed
#feed = Feed.find(params[:feed_id])
end
end
And in views my link is like this:
<div class="feed-like-<%= #feed %> " >
<%= link_to "like",{ :action => 'create', :controller => 'feed_likes', :feed_id => #feed, :user_id => current_user.id, :remote => true }, method: :post,class: "btn btn-primary" %>
</div>
And dislike link is like this:
<div class="feed-like-<%= #feed %> " >
<%= link_to "Dislike",{ :action => 'destroy', :controller => 'feed_likes', :feed_id => #feed, :user_id => current_user.id, :remote => true }, class: "btn btn-primary" %>
</div>
And my routes is like :
get "/feed_likes/:feed_id/feed_likes/:user_id" => "feed_likes#destroy"
post "/feed_likes/:feed_id/feed_likes/:user_id" => "feed_likes#create"
Here the issue is whenever someone wants to like the feed when I passes the url direclty it updated the database how can I restrict this only when user click the button only then it update the database not by url :
There is another issue with this I am using ajax onclick event it updated the database but when I click the like button fast it update the databse 2 or 3 times before the dislike partial appear . Is there any way I can use this .
I find a solution for this question it was very easy I was trying to generate the routes not in rails way so I did some changes . First I added
resources :feed_likes
and then replace the links like this :
<%= link_to "Dislike", feed_like_path(:feed_id => #feed, :user_id => current_user.id ), :confirm => 'Are you sure?',:remote => true, :method => :delete,data: { disable_with: "Processsing..." }, class: "btn btn-primary" %>
<%= link_to "like", feed_likes_path(:feed_id => #feed, :user_id => current_user.id ), :confirm => 'Are you sure?',:remote => true, :method => :post, data: { disable_with: "Processsing..." }, class: "btn btn-primary" %>

Rails: return only json

In my app there is a list of items which you can upvote. I want to make these votes with AJAX calls.
This is the view:
<ul class="list-groups">
<% #questions.each do |question| %>
<li class="list-group-item">
<%= link_to question.description, question_path(question) %>
<%= form_for(question, :url => url_for(:controller => 'vote', :action => 'vote'), method: :post, html: { class: 'form-inline' }) do |f| %>
<%= f.submit 'Up vote', class: "btn btn-default" %>
<%= f.hidden_field :id, :value => question.id %>
<% end %>
</li>
<% end %>
</ul>
And this the method that does it:
class VoteController < ApplicationController
respond_to :json
def vote
question_id = params[:question][:id]
user_id = current_user.id
vote = Vote.where(["question_id = :q", { q: question_id }]).where(["user_id = :u", { u: user_id }])
respond_to do |format|
if vote.nil?
#vote = Vote.new
#vote.question_id = question_id
#vote.user_id = user_id
#vote.save
format.html { render '/home/index' }
format.json { render :json => { :status => 'ok' } }
else
format.html { render '/home/index' }
format.json { render :json => { :status => 'failed', :msg => 'You already voted' } }
end
end
end
end
If I don't include this format.html { render '/home/index' } I am getting this error:
ActionController::UnknownFormat in VoteController#vote
But I don't want to render the page again, I am just loading the pieces of html that will change after the action with jQuery and ajax.
How can I respond only with the json?
Use respond_with instead of respond_to in your controller action.
respond_with do |format|
respond_to at the top of your controller is designed to work with respond_with in your controller action, whereas respond_to in your controller action ignores the respond_to that you've defined at the top of your controller.
Also make sure you are making a remote call, instead of a normall one if you want your request to go through AJAX.
<%= form_for(question, :url => url_for(:controller => 'vote', :action => 'vote'), method: :post, remote: true, html: { class: 'form-inline' }) do |f| %>
Note the remote: true part that is added as an argument to the form_for helper.
You need to include remote: true in form_for in order to make the call requests AJAX instead of HTML.
<%= form_for(question, :url => url_for(:controller => 'vote', :action => 'vote'), remote: true, method: :post, html: { class: 'form-inline' }) do |f| %>
Check out the Working with JavaScript in Rails documentation for more information.

Why my posting is taking me to wrong URL?

When I'm posting, it takes me to
example.com/shop.:community_name
instead of
example.com/shop/:community_name
My routes.rb
resources :communities, :path => "shop", do
resources :community_topics, :path => "topic", :as => :'topic'
end
_form.html.erb
<%= form_for #community, :html => { :class => 'form-horizontal' } do |f| %>
...
<%= f.submit nil, :class => 'btn btn-primary' %>
<%= f.submit 'Destroy',
:confirm => t('.confirm', :default => t("helpers.links.confirm", :default => 'Are you sure?')),
:class => 'btn btn-danger', :name => 'destroy' unless #community.new_record? %>
<% end %>
update action in communities_controller.rb I use to_param that's why using community_name
def update
#community = Community.find_by_community_name(params[:id])
respond_to do |format|
if #community.update_attributes(params[:community])
format.html { redirect_to communities_path(#community.community_name), notice: 'Community was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: "edit" }
format.json { render json: #community.errors, status: :unprocessable_entity }
end
end
end
It should be
... redirect_to community_path(#community.community_name) ...
in the update action of your CommunitiesController.
hate named routes...
redirect_to #community

Ajax doesn't work with Rails3.2

I want Follow button that changes to Un-Follow when its clicked.
But when it submits form, it doesn't do any at all.
Why?
My codes are like these
-----Action(users_controller.rb)-----
def set_follow
friend = User.find_by_username(params[:username])
if f = Friendship.find(:first, :conditions => { :user_id => current_user.id, :friend_id => friend.id})
f.destroy
flash[:notice] = "Now added to follow list"
respond_to do |format|
format.html { redirect_to set_follow }
format.js
end
#redirect_to :back
else
Friendship.create(:user_id => current_user.id, :friend_id => friend.id)
flash[:error] = "Now deleted from follow list"
respond_to do |format|
format.html { redirect_to set_follow }
format.js
end
#redirect_to :back
end
end
-----Form(users/index.html.erb)-----
<div id="follow_status">
<% if user_signed_in? && current_user.friends.find_by_id(user.id) %>
<%= link_to sanitize('<i class="icon-remove icon-white"></i> ') + 'Un-Follow', follow_user_path(user.username), :class => 'btn', remote: true %>
<% elsif current_user != user %>
<%= link_to sanitize('<i class="icon-ok icon-white"></i> ') + 'Follow', follow_user_path(user.username), :class => 'btn btn-primary', remote: true %>
<% end %>
</div>
-----JS View(set_follow.js.erb)-----
$("#follow_status").html("<%= escape_javascript(render f) %>");
Bit of a different method but I would just do this with JQuery
$('.btn').click( function() {
if( $('.btn').html() == 'Follow') {
$('.btn').html('Unfollow');
}
else if( $('.btn').html() == 'Unfollow') {
$('.btn').html('Follow');
}
});
​
This is just a bit of an example how you could do it. You would probably want to use a more specific chain of classes in the jquery

rails: "unknown action" message when action is clearly specified

I had hard time to figure out why I've been getting "unknown action" error message when I was do some editing:
Unknown action
No action responded to 11. Actions: bin, create, destroy, edit, index, new, observe_new, show, tag, update, and vote
you can see that Rails did mention each action in the above list - update. And in my form, I did specify action = "update".
I wonder if some friends could kindly help me with the missing links...
here is the code:
edit.rhtml
<h1>Editing tip</h1>
<% form_tag :action => 'update', :id => #tip do %>
<%= render :partial => 'form' %>
<p>
<%= submit_tag_or_cancel 'Save Changes' %>
</p>
<% end %>
_form.rhtml
<%= error_messages_for :tip %>
<p><label>Title<br/>
<%= text_field :tip, :title %></label></p>
<p><label>Categories<br/>
<%= select_tag('categories[]', options_for_select(Category.find(:all).collect {|c| [c.name, c.id] }, #tip.category_ids), :multiple => true ) %></label></p>
<p><label>Abstract:<br/>
<%= text_field_with_auto_complete :tip, :abstract %></label></p>
<p><label>Name: <br/>
<%= text_field :tip, :name %></label></p>
<p><label>Link: <br/>
<%= text_field :tip, :link %></label></p>
<p><label>Content<br/>
<%= text_area :tip, :content, :rows => 5 %></label></p>
<p><label>Tags <span>(space separated)</span><br/>
<%= text_field_tag 'tags', #tip.tag_list, :size => 40 %></label></p>
class TipsController < ApplicationController
before_filter :authenticate, :except => %w(index show)
# GET /tips
# GET /tips.xml
def index
#tips = Tip.all
respond_to do |format|
format.html # index.html.erb
format.xml { render :xml => #tips }
end
end
# GET /tips/1
# GET /tips/1.xml
def show
#tip = Tip.find_by_permalink(params[:permalink])
respond_to do |format|
format.html # show.html.erb
format.xml { render :xml => #tip }
end
end
# GET /tips/new
# GET /tips/new.xml
def new
#tip = session[:tip_draft] || current_user.tips.build
end
def create
#tip = current_user.tips.build(params[:tip])
#tipMail=params[:email]
#if tipMail
# TipMailer.deliver_email_friend(params[:email], params[:name], tip)
# flash[:notice] = 'Your friend has been notified about this tip'
#end
#tip = current_user.tips.build(params[:tip])
#tip.categories << Category.find(params[:categories]) unless params[:categories].blank?
#tip.tag_with(params[:tags]) if params[:tags]
if #tip.save
flash[:notice] = 'Tip was successfully created.'
session[:tip_draft] = nil
redirect_to :action => 'index'
else
render :action => 'new'
end
end
def edit
#tip = Tip.find(params[:id])
end
def update
#tip = Tip.find(params[:id])
respond_to do |format|
if #tip.update_attributes(params[:tip])
flash[:notice] = 'Tip was successfully updated.'
format.html { redirect_to(#tip) }
format.xml { head :ok }
else
format.html { render :action => "edit" }
format.xml { render :xml => #tip.errors, :status => :unprocessable_entity }
end
end
end
def destroy
#tip = Tip.find(params[:id])
#tip.destroy
respond_to do |format|
format.html { redirect_to(tips_url) }
format.xml { head :ok }
end
end
def observe_new
session[:tip_draft] = current_user.tips.build(params[:tip])
render :nothing => true
end
end
the quick answer is that form_tag doesn't support :action as an option, you want to be passing a string as a path in. A slightly longer answer is you shouldn't be using form_tag anyways for a model edit form, you should be using form_for.
what rails are you using? .rhtml is pretty old, rails generators should be giving you .html.erb files. if it is something even remotely recent, you should be able to use
<% form_for #tip do |f| %>
<%= f.label :title, 'Title' %><br />
<%= f.text_field %>
... etc
<% end %>

Resources