Rails passing params in link_to how to make it secure - ruby-on-rails

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" %>

Related

Rails Problems in IE - double storing in database

I've got several problems with a Rails 4.2.1 and Ruby 2.1 application when testing in IE. If I save something to a database and do a redirect, the values are saved twice in the database.
Does anyone have this as well?
Save Methode in controller:
if request.post?
#question.attributes = params[:question]
if #question.save
flash.now[:notice] = t("flash.saved")
update_answers params
redirect_after_save #question
end
end
def update_answers params
if !params[:add].nil?
params[:add].each do | id, data |
answer = Answer.new
data[:question_id] = #question.id
answer.update_attributes data
end
end
end
def redirect_after_save q
if params[:action_after_save] == 'back'
flash[:notice] = I18n.t("flash.saved")
redirect_to :controller => :lessons, :action => :edit, :id => q.lesson_id
end
if params[:action_after_save] == 'new'
flash[:notice] = I18n.t("flash.saved")
redirect_to :action => :new, :id => q.lesson_id
end
if params[:action_after_save] == 'test'
flash[:notice] = I18n.t("flash.saved")
redirect_to :action => :test, :id => q.id
end
end
I'm not using turbolinks.
View Code:
<%= f.submit t("main.save"), :icon => :save %>
<%= t("question.or_save_and") %>:
<% [[t('question.after_save_back'), 'back'],
[t('question.after_save_new'), 'new'],
[t('question.test_question'), 'test']].each do |it| %>
<%= f.submit(it.first, :disable_with => "saving",
:onclick => "$('#edit_question').append('<input type=\"hidden\" name=\"action_after_save\" value=\"" + it.second + "\" />');",
:icon => :save) %>
<% end %>
this is the Code which is called during saving.
def multiple_choice
#question = Question.find params[:id]
return false unless check_authorization #question
add_edit_breadcrumbs #question
if request.post?
#question.attributes = params[:question]
if #question.save
flash.now[:notice] = t("flash.saved")
SLACKNOTIFIER.ping "Bevor update answers"
update_answers params
SLACKNOTIFIER.ping "After update answers"
redirect_after_save #question
end
end
end
the whole code is called twice in IE ...
Adding the property:
disable_with: 'button-text'
to the submit button solved the problem (from comments above).

Rails Ajax render partial with local variable

Hey I am trying to render a partial using ajax everything work in rails normal form but when I am rendering a partial using ajax local variables don't work I am trying to create a like and dislike system for that I have created a model called FeedLike here I can like and dislike using simple create and destroy but when I am using ajax and there I am calling this action below :
$('#feed_like').html("<%= j render :partial => 'shared/dislike', :locals => { feed: #feed= #feed} %>");
I am getting the error No route matches
{:action=>"destroy", :controller=>"feed_likes", :feed_id=>nil, :user_id=>1}
And my dislike link is like this it is a partial which is under :
<div id="feed_dislike">
<%= link_to "Dislike",{ :action => 'destroy', :controller => 'feed_likes', :feed_id => #feed, :user_id => current_user.id }, class: "btn btn-primary" %>
</div>
everything work fine when I am not using ajax but when I am rendering partial why #feed is not getting any value what am I supposed to do . To get the value of feed.id . feed.id is coming from and model called Feed and it is under look and there I am rendering these two forms using partials .
now I am pasting some codes which will give you what I am doing :
#shared/_feed.html.erb
<% if #feed_items.try(:any?) %>
<ol class="microposts">
<%= render #feed_items %>
</ol>
<%= will_paginate #feed_items %>
<% end %>
And #feed_items is coming from :
#feeds/_feed.html.erb
<li id="feed-<%= feed.id %>">
<%= image_tag(current_user.avatar.url(:thumb), :size => '50x50') %>
<span class="user"><%= link_to feed.user.name, feed.user %></span>
<span class="content"><%= feed.content %></span>
<span class="timestamp">
Posted <%= time_ago_in_words(feed.created_at) %> ago.
</span>
<% #like =FeedLike.where(:user_id => "#{current_user.id}", :feed_id => "#{feed.id}")
%>
<%= render :partial => 'shared/feed_like', locals: { feed: #feed= feed.id} %>
</li>
And now feed_like partial :
#shared/_feed_like.html.erb
<% if #like.count == 0 %>
<%= render :partial => 'shared/like', locals: { feed1: #feed= #feed} %>
<% else %>
<%= render :partial => 'shared/dislike', locals: { feed: #feed} %>
<% end %>
Controllers code for :
class FeedsController < ApplicationController
before_action :authenticate_user! ,only: [:create, :destroy]
def create
#feed = current_user.feeds.build(feed_params)
#feed_likes = FeedLike.new
if #feed.save
#redirect_to root_url
respond_to do |format|
format.html { redirect_to root_url }
format.js
end
else
respond_to do |format|
format.html { redirect_to root_url }
format.js { render :js=>'alert("you can not leave post empty");' }
end
end
end
def destroy
end
private
def feed_params
params.require(:feed).permit(:content)
end
end
FeedsLike controller :
class FeedLikesController < ApplicationController
before_action :authenticate_user! ,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 ' }
else
end
end
end
def create
#feed_likes = FeedLike.find_or_create_by(:feed_id => params[:feed_id],:user_id =>params[:user_id])
respond_to do |format|
if #feed_likes.save
format.html { redirect_to root_url, notice: 'Like ' }
format.js
else
end
end
end
def delete
end
def destroy
#feed_likes = FeedLike.where(:feed_id => params[:feed_id],:user_id =>params[:user_id])
respond_to do |format|
if #feed_likes.destroy_all
format.html { redirect_to root_url, notice: 'Unlike ' }
else
end
end
end
def feed_like_params
params.require(:feed_like).permit(:user_id, :feed_id)
#params[:market_place]
end
end
And staticpage controller :
class StaticPagesController < ApplicationController
before_action :authenticate_user!
def home
if user_signed_in?
#feed_likes = current_user.feed_likes.new
#feed = current_user.feeds.build
#feed_items = current_user.feed.paginate(page: params[:page])
# #likes = Feed.find(:all,
# :select => '"feeds".id, "feeds".content, count("feed_likes".id) as Like',
# :from => :feeds,
# :left_join => '"feed_likes"',
# :on => '"feeds".id = "feed_likes"."feed".id',
# :limit => 5
# )
# #like =Feed.find_by_sql "
# SELECT id
# FROM feed_likes
# WHERE user_id = #{current_user.id}
# AND feed_id =#{feed.id}
# LIMIT 0 , 30
# "
end
end
def help
end
def about
end
def contact
end
end
your feed is nil which is why it is crashing
please add this in your feed_likes controller.
before_action :get_feed ,only: [:create, :destroy]
and at the bottom add this method
def get_feed
#feed= Feed.find(params[:feed_id])
end
Your feed definition looks wrong in your javascript file. Try this instead:
$('#feed_like').html("<%= j render :partial => 'shared/dislike', :locals => { feed: #feed} %>");

rails render is not working in create action

In my controller I coded like this
class CompanyUploadRequestsController < ApiController
def index
respond_to do |format|
format.html { render action: "index" }
end
end
def create
puts params
respond_to do |format|
format.html { render action: "index" }
end
end
def new
end
end
and in my view new.html.haml file
- page_title("Upload Company")
%h1 Upload Company
%hr
#upload-form
= simple_form_for(#company_upload, :as => :company_update, :url => company_upload_requests_path(#company_upload), :html => { :class => 'file-style'}) do |f|
= f.error_notification
.form-inputs
= f.input :requestname, :label => false, :id => "request_name_input"
= f.input :file,:as => :file, :label => false, :id => "file_select_input"
.form-actions
!= link_to 'Cancel', company_upload_requests_path, :class => 'btn'
= f.button :submit, 'Upload', :class => 'btn-primary'
In my index.html.haml file I have this
- page_title("Upload Company")
%h1 Company index
= link_to("Upload File", new_company_upload_request_path, :class => "btn btn-primary pull-right")
The problem is when I click upload button its not render to index page from create
Here I got the log like this
Processing by CompanyUploadRequestsController#create as HTML
Parameters: {"utf8"=>"?", "authenticity_token"=>"oygIP62E4GHefhN9OnvB3sKhddIb4CN/izfvF5GQtuI=", "company_update"=>{"requestname"=>""}, "commit"=>"Upload"}
Rendered company_upload_requests/create.html.haml within layouts/application (9.8ms)
How can I render to index action and view index file content.
Use like this.
def index
#company_uploads = ModelName.all
respond_to do |format|
format.html
end
end
No need to render index action in index response.
def create
puts params
respond_to do |format|
format.html { render "index" }
end
end
Change the render in your create method to redirect_to
def create
puts params
respond_to do |format|
format.html { redirect_to action: "index" }
end
end
For more explanation on render vs redirect_to, see this SO Question or this.

rails delete a record with multiple conditions

I'm trying to use .find or .where to find a certain record in my database to delete, but I'm having trouble...
I have this in my routes
resources :objects do
delete 'item' => 'objects#item_destroy', :as => :item_destroy
end
In my controller
def item_destroy
#object = Object.find(params[:object_id])
#puser = Puser.find_by_user_id(current_user)
if #mine = Mine.where(:puser_id => #puser).where(:object_id => #object)
#mine.destroy
respond_to do |format|
format.html { redirect_to :back }
format.xml { head :ok }
end
end
end
However I'm getting this error:
wrong number of arguments (0 for 1)
My link to destroy is this:
<%= link_to "Delete me", object_item_destroy_path, method: :delete, :class => "pure-button pure-button-primary" %>
Can someone assist me?
Thanks!
EDIT::
also, when I'm only getting these parameters:
{"_method"=>"delete",
"authenticity_token"=>"fdsagfHFUWlfiwoqobGBW92&9",
"object_id"=>"21"}
I'm not getting puser_id?
Try this:
<%= link_to "Delete me", object_item_destroy_path(object_id: #object), method: :delete, :class => "pure-button pure-button-primary" %>
UPDATE:
Change you objects_controller.rb file's method:
def item_destroy
#object = Object.find(params[:object_id])
#puser = Puser.find_by_user_id(current_user)
if #mine = Mine.where(:puser_id => #puser).where(:object_id => #object).first
#mine.destroy
respond_to do |format|
format.html { redirect_to :back }
format.xml { head :ok }
end
end
end
Here, when you say: Mine.where(:puser_id => #puser).where(:object_id => #object), it will give you an ActiveRecord::Relation object, not the Mine's object, and hence destroy method is not available the way you're trying to invoke it.
I also encourage you to use associations here. Like:
#puser.mines.where(:object_id => #object).first
# or
#puser.mines.find_by_object_id(#object)
<%= link_to "Delete me", object_item_destroy_path**(:id => "something" or the object you want to delete)**, method: :delete, :class => "pure-button pure-button-primary" %>
Yup, no id is being passed in because no id is being put into the link.

Rails post delete functionality giving template error

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 %>

Resources