dannymcc
dannymcc

Reputation: 3814

Create action to change boolean value in Rails 3

I have a simple model for suggestions in my Rails 3 application. I am trying to add a simple link_to link on the index view that when clicked marks the suggestion as approved.

So far I have the following code:

routes.rb

resources :suggestions do
 get :approve
end

suggestions_controller.rb

def approve
 @suggestion = Suggestion.find(params[:id])
 @suggestion.update_attribute(:approved, 'true')
 @suggestion.update_attribute(:approved_on, Time.now)
 redirect_to suggestion_path
end

suggestion.rb

attr_accessible :author, :details, :localip, :title, :approved, :approved_on

schema.rb

create_table "suggestions", :force => true do |t|
 t.string   "title"
 t.string   "author"
 t.text     "details"
 t.string   "localip"
 t.datetime "created_at",                     :null => false
 t.datetime "updated_at",                     :null => false
 t.boolean  "approved",    :default => false
 t.datetime "approved_on"
end

index.html.erb (suggestions)

<% if @suggestion.approved? %>
    <%= @suggestion.approved_on %>
<% else %>
    Not yet approved. (<%= link_to "Approve", approve_suggestion_url(@approve), :method => :put %>)
<% end %>

When using the above code, I get the following exception error:

undefined method `approved?' for nil:NilClass

Am I missing a step out somewhere something?

Upvotes: 1

Views: 1767

Answers (1)

Kulbir Saini
Kulbir Saini

Reputation: 3915

Most probably, the code you have posted is inside an each loop like

<% @suggestions.each do |suggestion| %>
  ...
  <% if @suggestion.approved? %>
    <%= @suggestion.approved_on %>
  <% else %>
    Not yet approved. (<%= link_to "Approve", approve_suggestion_url(@approve), :method => :put %>)
  <% end %>
<% end %>

You need to use suggestion variable instead of @suggestion instance variable. Also, to construct suggestion approve url, you'll need to use suggestion instead of @approve. Code should be like

  <% if suggestion.approved? %>
    <%= suggestion.approved_on %>
  <% else %>
    Not yet approved. (<%= link_to "Approve", approve_suggestion_url(suggestion), :method => :put %>)
  <% end %>

Also, you should modify your routes.rb to reflect that approve action is a member action.

resources :suggestions do
  put :approve, on: :member
end

To understand the difference between member and collection routes, read difference between collection route and member route in ruby on rails?.

Upvotes: 1

Related Questions