Domanda

Iam kinda stuck at this problem. Trying to update a non mass-assignable attribute in the job model from an admin view. I need a button which trigger an action method in the admin controller which just changes job's isactive value to true.

In admin controller:

     def approve
    @job.update_attribute(:isactive = true)
    if @job.save
      redirect_to(:action => :show)
      flash[:notice] = "Job Approved"
    else
      render 'show'
    end
  end

In jobs/1 view

<div style="text-align:center;" class="widget">
<%= form_for(@job, :url => url_for(:controller => 'admin', :action => 'approve'), :html => {:id => "contact_form", :class => "g-form"}) do |f| %>

<%= button_tag( :class => "g-btn type_default") do %>
<i class="icon-share-alt icon-white"></i>Approve this job 
<% end %>
 <% end %>      
<% end %>   

No matter what i do this form gets submitted to the job update action and show job successfully updated rather than the notice "Job approved" from the approve action in admin.

I have added the following route as well. but not sure what iam doing wrong. I need a simple button (ideally a block because of the styling req) which sets job's isactive field to true.

match "jobs/:id", :via=>:post, :controller=>"admin", :action=>"approve"
È stato utile?

Soluzione

Mass assignment was designed to protect precisely against what you're trying to do here so ideally speaking, you should add it to a whitelist (attr_accessible) if you need to modify it.

However, there are a few issues with your controller action that will need to be addressed even if you get the isactive attribute whitelisted.

@job.update_attribute(:isactive = true) is not valid. update_attribute does not handle assignments, the correct syntax is update_attribute(attribute, value) so it should be:

@job.update_attribute(:isactive, true)

Also, the update_attribute method calls save on the passed object. Calling @job.save after update_attribute (provided there is no other code assigning attributes) is redundant.

A better way to write this method would be:

def approve
  if @job.update_attribute(:isactive, true)
    redirect_to(:action => :show)
    flash[:notice] = "Job Approved"
  else
    render 'show'
  end
end

However, if you cannot modify the model and are not worried about callbacks or validation, you can update the database column directly with update_column (or update_columns in Rails 4):

def approve
  if @job.update_column(:isactive, true)
    redirect_to(:action => :show)
    flash[:notice] = "Job Approved"
  else
    render 'show'
  end
end
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top