Rails passing params in link_to how to make it secure

238 views
Skip to first unread message

nilay singh

unread,
Aug 10, 2015, 3:36:52 PM8/10/15
to Ruby on Rails: Talk

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 ' }

                        else

                        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
                        else

                        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
                       else

                       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 .

Message has been deleted

nilay singh

unread,
Aug 10, 2015, 5:47:40 PM8/10/15
to Ruby on Rails: Talk
http://ec2-52-6-228-48.compute-1.amazonaws.com/ Here is the live application I am working on here there is a like button when I click on like button it update my database that it liked and dislike button appear it work well but when I click very fast 3 times before dislike appear it sneds three ajax request . And it is a very bad thing how to fix this 
Message has been deleted

paul h

unread,
Aug 11, 2015, 1:23:45 PM8/11/15
to Ruby on Rails: Talk
Hi Nilay,

The first thing I would do, would be to strip out your controller code and move your logic into the model. You've got too much going on in your create and destroy actions. This should be in the model.

The controller should be responsible for receiving the request, and sending the response back to the browser in the correct format, while the model should be responsible for handling the business logic.
Think about what is happening when you click the link.

A request is sent to the server, which is picked up by your app and routed to your controller, which then handles the request, and sends a response back to the browser - this is going to take longer then it takes for you to click your link multiple times - therefore your app handles each click exactly as you have designed it to.

If this situation becomes too problematic, then it is probably a code smell that your design is wrong and needs to be looked at again.

I don't get why your dislike button only appears after a click on the like button. Do you really need to like something before you can dislike it?

A simple fix would be to add some Javascript that removes the link from the page after the first click before the request is sent to the browser, and maybe display an indictor/spinner that informs the user that the click is currently being handled.

Regards

Paul

nilay singh

unread,
Aug 11, 2015, 2:03:24 PM8/11/15
to Ruby on Rails: Talk
Thanks for reply paul . If you can suggest me how should I use these controllers code in model I am new to rails so I am not aware about this method . And for this problem I found a way to delay the process  using disable_with method in rails and it fix the problem by delaying the process . 

So here is the solution code  :

<%= link_to "Dislike",{ :action => 'destroy', :controller => 'feed_likes', :feed_id => @feed, :user_id => current_user.id, :remote => true },data: { disable_with: "Processsing..." }, class: "btn btn-primary" %>


And paul there is one more problem . I need to fix that you can see the url of my links are passsing the params is it a right way if yes then ok but the problem is When I paste the url direclty in the browser it get updated how can I prevent this .

On Tuesday, August 11, 2015 at 1:06:52 AM UTC+5:30, nilay singh wrote:

paul h

unread,
Aug 11, 2015, 5:34:11 PM8/11/15
to Ruby on Rails: Talk
Hi Nilay,

Ruby and Rails are changing all the time, so it's always useful to post which versions you are using, if I missed it in your post I apologise.

On Tuesday, August 11, 2015 at 7:03:24 PM UTC+1, nilay singh wrote:
Thanks for reply paul . If you can suggest me how should I use these controllers code in model I am new to rails so I am not aware about this method .
 
In which case I would suggest following a few Rails tutorials. A quick google for 'Rails Tutorials' is a good starting point. You will end up getting more done, faster, if you take the time out to follow one or two of those.

You should also have a decent understanding of Ruby and MVC frameworks.

That said, I'll assume the following and try to help.

You have a model: Feed
And a model: FeedLike

Feed has_many :feed_likes
FeedLike belongs_to :feed

Your create action could be as simple as follows:

def create
    @feed_like = FeedLike.find_or_create_by(:feed_id => params[:feed_id],:user_id =>params[:user_id])
    @feed_like.increment
    respond_to do |format|
        if @feed_like.save
            ...
        end
    end
end

Then, in your FeedLike model you could add the following method:

def increment
    self.feed.like_count ++
end

(If you have your models set up correctly then the increment method should be fine because rails will create the feed method on the FeedLike model, which points to the Feed model. This then gives you access to the like_count method of the Feed model.)

Your destroy method could be as follows:

def destroy
    @feed_like = FeedLike.where(feed_like_params)
    @feed_like.decrement
    respond_to do |format|
        if @feed_like.destroy 
            ...
        end
    end
end

(I'm not sure why you're calling destroy_all)

Then in your FeedLike model:

def decrement
    self.feed.like_count --
    self.feed.save
end

You need to call save here, because calling destroy on the FeedLike model won't automatically save the Feed model relation. 

Personally I would set this all up to go through the Feed controller, which would also make your links and routes easier to set up.

 
And for this problem I found a way to delay the process  using disable_with method in rails and it fix the problem by delaying the process . 

So here is the solution code  :

<%= link_to "Dislike",{ :action => 'destroy', :controller => 'feed_likes', :feed_id => @feed, :user_id => current_user.id, :remote => true },data: { disable_with: "Processsing..." }, class: "btn btn-primary" %>


And paul there is one more problem . I need to fix that you can see the url of my links are passsing the params is it a right way
 
Probably not the way you have set your routes up. Where did you get the information from to create them as you have?

You don't seem to be doing anything out of the ordinary to need such custom routes for your create and destroy methods, so, if you use the following method for your controller routes you will get the standard routes that you should be working with.

In routes.rb

resources :feed_likes

What you will need to do, is to pass the feed_id and the user_id as parameters on your links rather than coding them into the route as you have. You can also tidy up your links using the routes helper methods such new_feed_like. 

Run 'rake routes' from the command line to see what your routes look like and what helpers are available.
 
if yes then ok but the problem is When I paste the url direclty in the browser it get updated how can I prevent this .
 
Fix your routes, then see if this is still a problem. 

Obviously all the above is untested, and it's getting late here, so hopefully I've helped you on the right path.

Regards

Paul

Frederick Cheung

unread,
Aug 12, 2015, 12:03:34 PM8/12/15
to Ruby on Rails: Talk

On Monday, August 10, 2015 at 8:36:52 PM UTC+1, nilay singh wrote:

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 :



You shouldn't be doing something that changes the database from a GET route. I'd change that route to use the delete method instead of get (and then change the link too)

Fred
Message has been deleted

nilay singh

unread,
Aug 15, 2015, 11:28:26 PM8/15/15
to rubyonra...@googlegroups.com

I solve the issue

On Aug 16, 2015 8:56 AM, "Elizabeth McGurty" <emcg...@gmail.com> wrote:
Nilay,

What's the status of your effort here? 

Liz

--
You received this message because you are subscribed to a topic in the Google Groups "Ruby on Rails: Talk" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/rubyonrails-talk/UQznBN9IU_s/unsubscribe.
To unsubscribe from this group and all its topics, send an email to rubyonrails-ta...@googlegroups.com.
To post to this group, send email to rubyonra...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/rubyonrails-talk/df9d2950-e532-4104-b7a5-5b2d65956716%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Message has been deleted

nilay singh

unread,
Aug 16, 2015, 1:31:50 AM8/16/15
to rubyonra...@googlegroups.com
Sure for my first question I made some changes to my routes file here
I use resources for my model which generated the routes and then I
write this code in link : This is what I change in route :

resources :feed_likes, param: :feed_id


and this is my links which I am passing the params :

it is for dislike :

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

and this is for like :

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

And for delaying the process I use disable_with


It served my purpose

On Sun, Aug 16, 2015 at 10:16 AM, Elizabeth McGurty <emcg...@gmail.com> wrote:
> Would you kindly share your results?
>
> --
> You received this message because you are subscribed to a topic in the
> Google Groups "Ruby on Rails: Talk" group.
> To unsubscribe from this topic, visit
> https://groups.google.com/d/topic/rubyonrails-talk/UQznBN9IU_s/unsubscribe.
> To unsubscribe from this group and all its topics, send an email to
> rubyonrails-ta...@googlegroups.com.
> To post to this group, send email to rubyonra...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/rubyonrails-talk/ce36e9d2-245b-47e5-95c0-443944b489f8%40googlegroups.com.

Colin Law

unread,
Aug 16, 2015, 3:32:50 AM8/16/15
to Ruby on Rails: Talk
On 16 August 2015 at 04:27, nilay singh <nilay...@gmail.com> wrote:
> I solve the issue

Do you think it might be good manners to thank those that provided
helpful ideas?

Colin

prionko

unread,
Aug 16, 2015, 4:42:59 AM8/16/15
to Ruby on Rails: Talk
Nilay,

Why did u use Feed and FeedLike model? The solution provided by Liz is good. You can pass binary values for updating the like and dislike value, instead of having two different models.

And definitely your code needs lot of cleanups. Google for code cleanups, refactoring in rails.

-Saurav

Reply all
Reply to author
Forward
0 new messages