gitastic
gitastic

Reputation: 526

Rails 4, update model attribute with link_to

Hoping someone can help with this problem.

I have 2 controllers/models: (1)User has many (2)Reviews. Reviews belongs to Users.

I want to simply update a flag attribute in the Review model, using link_to in a view. If user clicks the 'flag' link, it will update/patch the model attribute, 'flag', in Model 'Review' to integer '1'.

Something like this?

<%= link_to 'Flag', [review.user, review.flag], method: :put, data: { confirm: 'Are you sure?' } %>

Any help appreciated!

Upvotes: 1

Views: 1064

Answers (3)

Andrew
Andrew

Reputation: 239097

The Rails link_to helper can do this. The trick is in specifying query params. If you're passing an array as the URL, it can be achieved like this:

<%= link_to 'Flag', [review, { review: { flag: 1 } }], method: :patch, data: { confirm: 'Are you sure?' } %>

This would result in a request like this:

Started PATCH "/reviews/123?review%5Bflag%5D=1"
Processing by ReviewsController#update as 
  Parameters: {"review"=>{"flag"=>"1"}, "id"=>"123"}

You can also use the generated URL helper methods to achieve the same thing:

<%= link_to 'Flag', review_path(review, review: { flag: 1 }), method: :patch, data: { confirm: 'Are you sure?' } %>

Upvotes: 0

kurenn
kurenn

Reputation: 1055

You could do something like:

reviews_controller.rb

class ReviewsController < ApplicationController

  def flag
   review = Review.find(params[:id])
   review.flag!
   redirect_to :back #or wherever you want to redirect to
  end
end

routes.rb

resources :reviews do
 patch :flag, on: :member #reviews/1/flag
end

reviews/show.html.erb

<%= link_to "Flag", flag_review_path(review), method: :patch,  data: { confirm: 'Are you sure?' }%>

models/review.rb

class Review < ActiveRecord::Base

 def flag!
  update_attribute(:flag, 1)
  #If you don't want callbacks or validations use this
  #update_columns(:flag, 1)
 end
end

Hope this helps!

Update: member should be :member.

Upvotes: 5

apebeast
apebeast

Reputation: 368

Your reviews_controller.rb method should look like this:

before_action :set_review, only: [:show, :edit, :update, :destroy, :put]

def put
    @review.update(flag: 1)
end

private
    def set_review
        @review = Review.find(params[:id])
    end
end

Assuming that you have flag set up as an integer in your schema.

Upvotes: 0

Related Questions