Mel
Mel

Reputation: 2715

Toggle Boolean in Rails 4

I'm trying to figure out how to toggle a boolean attribute from true to false in my Rails 4 app. I've read lots of similar problems in earlier versions of rails, but things have changed in the routes and other things that make those solutions different to what I need.

I have a projects model, which includes an attribute called draft. If :draft is false, I want to include a link in my show that will make :draft update to true.

I have tried several js solutions from other answers but I can't figure out the logic that I need for this.

Has anyone done this in Rails 4?

I have tried Zoran's suggestion below as follows:

Projects controller:

 def toggle_draft
    @project = Project.find(params[:id])
    @project.draft = true
    @project.save
    redirect_to project_path(@project)
  end

Projects show:

  <% if @project.scope.finalise.draft %>
      <%= link_to toggle_draft_path(id: @scope.id)
  <% end %>

Routes:

resources :finalise

  patch '/toggle-draft', to 'finalises#toggle_draft', as: 'toggle_draft'

I have updated my schema to make a model called scope and a model called finalise. Scope belongs to projects and Finalise belongs to Scope.

I have set Scope to accept nested attributes for Finalise and Projects to accept nested attributes for Scope. I have white labelled the params in projects and scope and finalise.

I now have two partials in my Finalise view, one for draft and one for finalise. In the draft partial I have tried:

<% if @project.scope.draft == true %>
    <%= link_to toggle_draft_path(id: @project.scope.id) %>
<% end %>

In my finalise controller, I have the toggle method, adapted from that Zoran suggested:

 def toggle_draft
    @finalise = Finalise.find(params[:id])
    @finalise.draft = true
    @finalise.save
    redirect_to project_path(@project)
  end

above and my routes are:

 resources :finalises
   patch '/toggle-draft', to 'finalises#toggle_draft', as: 'toggle_draft'

I try to start the server to test this, but I get an error which says:

rb:4: syntax error, unexpected tSTRING_BEG, expecting keyword_do or '{' or '(' (SyntaxError) patch '/toggle-draft', to 'finalises#toggle_draft', as: ...

When i comment the route line out of finalises and try to start the server, I get a further error that says:

PG::UndefinedColumn: ERROR: column finalises.scope_id does not exist LINE 1: SELECT "finalises".* FROM "finalises" WHERE "finalises"."s...

My finalise table has a column for scopes_id (integer).

Thank you

Upvotes: 0

Views: 1270

Answers (1)

Zoran
Zoran

Reputation: 4226

You can do something like the following to accomplish a draft toggle for your projects:

  1. Expose a route for the link on your show page:

routes.rb:

patch '/toggle-draft', to: 'projects#toggle_draft', as: 'toggle_draft'
  1. Define a toggle_draft in your ProjectsController:

projects_controller.rb

def toggle_draft
  @project = Project.find(params[:id])
  @project.draft = true
  @project.save
  redirect_to project_path(@project)
end
  1. Finally, in your markup for the show page you can conditionally display the link:

projects/show.html.erb:

<% if @project.draft %>
  <%= link_to 'Toggle', toggle_draft_path(id: @project.id), method: :patch %>
<% end %>

Hope this was helpful.

Upvotes: 1

Related Questions