0

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

5
  • show some code that you've tried and we'll help from there. Commented Jun 7, 2015 at 11:56
  • I set out Zoran's suggestion above Commented Jun 7, 2015 at 12:05
  • To resolve the PG:UndefinedColumn error, you must add a scope_id column in the finalises table, and run the necessary migration(s). Commented Jun 8, 2015 at 1:41
  • your syntax error is because you need an end after the patch line in your routes. Commented Jun 8, 2015 at 8:30
  • Hi Max, thanks for the suggestion, I have changed the route file to resources :finalises do patch '/toggle-draft', to: 'finalises#toggle_draft', as: 'toggle_draft' end but I still get this error: No route matches [GET] "/toggle-draft" Commented Jun 8, 2015 at 8:48

1 Answer 1

1

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.

Sign up to request clarification or add additional context in comments.

7 Comments

Since it's a destructive action, I'd rather do that in POST. Or more RESTfully -- PATCH. By using GET one can get some special effects with caching.
Hi Zoran, I'm trying this, but get an error with the route => expecting keyword_do or '{' or '(' get '/toggle-draft', to 'projects#toggle_draft', as:
My mistake - i forgot to include a : in the routes.rb file. I updated my answer. Take a look at the line in the routes.rb again, it should fix that error. Hope it helps!
Hi Zoran, thnaks for the help with the route. I still get this issue. Do you know what that might mean I need to do? PG::UndefinedColumn: ERROR: column finalises.scope_id does not exist LINE 1: SELECT "finalises".* FROM "finalises" WHERE "finalises"."s... ^
That error seems to say that when you created the Finalize/Scope models, you may not have run the necessary database migrations - it's saying the scope_id column doesn't exist in the finalizes table.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.