Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails 3 how do I use link_to to change the value of a boolean in the db?

I'm trying to create a simple link that will allow an admin to approve a user on my website

quite similar to what this guy was trying : In Rails 3 how do I use button_to to change the value of a boolean?

Here's how it was supposed to work :

  1. Admin clicks the link to approve a user
  2. The link calls the activate function in UsersController
  3. The active function calls that users model
  4. the user model updates the approved attribute to true and saves it

and here's how I was going to do it

in my users#index view

 <% @users.each do |user| %> 
 <%= link_to 'Approve', :action => "index", :method => 'activate', :id => user.id, :class => 'btn btn-mini btn-danger' %> 
<% end %> 

in my userController

def activate
  @user = User.find(params[:user])
  @user.activate_user
end

in my user model

def activate_user 
  self.approved = 'true'
  self.save
end

and my routes

devise_for :users, :controllers => { :registrations => "registrations" }

resources :users do
  member do
    get 'activate'
    put 'activate'
  end
end

match "users/:id/activate" => "users#activate"

Now when I click the link (to approve users), I'm sent back to the user index page (like I'm supposed to) but the user field "approved" is still set to false :I

The URL I get after clicking the link :

  http://localhost:3000/users?class=btn+btn-mini+btn-danger&id=2&method=activate

Any ideas?

UPDATE

As suggested iv added the URL to the link_to helper

<% @users.each do |user| %> 
  <%= link_to "Approve", :controller => "users", :id => user.id, :action => "activate", :method => :put, :approved => true %> 
<% end %>

When I click the helper link I get

wrong number of arguments (1 for 2) 

in app/controllers/users_controller.rb:7:in `activate'

def activate
  @user = User.find(params[:id])
  @user.update_attribute(params[:user])
  redirect_to "/users?approved=false"
end

line 7 where the error is @user.update_attribute(params[:user])

What else should I put there?

oh and here is my route for this method

match "/users/:id/activate" => "users#activate"

UPDATE V2 So I have changed that update line to :

@user.update_attributes(@user.approved, "true")

and it seems to do everything i want it to do except changing the value to true !

I've also tried to use 1 for true (and the update_attribute function) and non-strings.. running out of ideas here lol

The solution

Well this is awkward but so it happens that in my user model i had attr_accessor :approved this resulted in that the model never went to the database to update the :approved column BUT instead it updated the local variable :approved so next time when I looked at the column then of course the :approved value had not changed

tldr? if you have attr_accessor in your model with the same name as the column your trying to update => remove it

like image 649
Matti Avatar asked Nov 01 '12 17:11

Matti


2 Answers

You can update the code below

You View

<% @users.each do |user| %> 
<%= link_to 'Approve', active_user_path(user) %> 
<% end %>

You Controller

def activate
  @user = User.find(params[:id])
  if @user.update_attribute(:approved, true)
    redirect_to "something"
  else
   render "something"
  end 
end

Your routes

match "users/:id/activate" => "users#activate", :as => "active_user"

Hope can help you.

like image 53
khanh Avatar answered Oct 23 '22 03:10

khanh


Looks like you aren't calling link_to properly. Notice that you have the action as a http parameter and not part of the URL.

The URL should be

http://localhost:3000/users/123/activate

Look at the examples on this page:

http://apidock.com/rails/ActionView/Helpers/UrlHelper/link_to

I think you need to use the :controller => 'users', :action => 'activate'.

Remember you can use a string here for the path as well: "/users/${@user.id}/activate"

like image 35
RonanOD Avatar answered Oct 23 '22 03:10

RonanOD