0

I have the following modeling:

  User 
  has_many :projects

  Project 
  belongs_to :user
  has_many :tasks 

  Task 
  belongs_to :project
  has_many :workIntervals 

  WorkInterval 
  belongs_to :task

I have it as nested resources such as:

resources :projects do
  resources :tasks do
    resources :work_intervals
  end
end

I get the user from the current_user who is signed in, that is why I don't have in the URL.

A WorkInterval from a Task is used to record the time(s) that the User has been working on a Task. So for example Monday from 10am to Tuesday at 10am. That is a task can have several WorkIntervals.

I would like to be able to have a button which would be "Start working" when I am in the task page. But I fail to see what would be what I should put in that button, is it an AJAX call? If so, what should I pass in the form_for? So, say the URL is:

/projects/:project_id/tasks/:task_id

And I want to have a button that is called "Start Working" than when triggered, creates a new WorkInterval associated with that task.

What would be the code to do a correct way to do so?

Zippie
  • 5,657
  • 6
  • 28
  • 44
Hommer Smith
  • 22,976
  • 49
  • 140
  • 254

2 Answers2

0

Effectively you want to create a new work_interval at click of a button. I see two ways you can accomplish this.

  1. you can create a form that will POST to the path you specified and the link will be the submit button. Something like this:

    <%= form_for [@project, @task, Task.work_intervals.new] do |f| %>
    <%= submit_tag "Start working" %>
    <% end %>
    
  2. THe other way would be to modify the default resource routing, giving you access to create method on WorkIntervals controller via GET action.

    resources :projects do
      resources :tasks do
        resources :work_intervals do
          get :create, as: :create, on: :collection
        end
      end
    end
    

    The you will have a link_to for the above action.

Sergey Kuleshov
  • 444
  • 4
  • 8
  • the `get :create, as: :create, on: :collection` isn't needed since the `resources` handles it already. – Zippie Apr 11 '13 at 16:29
  • No, create action is only available via POST, in this case we are exposing this via GET so we can have plain link pointing to it. – Sergey Kuleshov Apr 11 '13 at 16:33
  • You can create links with HTTP POST methods, no need to make it a GET. also, read more here about the authenticity token and why not to use GET while modifying the DB: http://stackoverflow.com/questions/941594/understand-rails-authenticity-token – Zippie Apr 11 '13 at 16:44
0

The button code to perform the AJAX call should be something like this (if i haven't got the path right, please render rake routes and see what the path of work intervals CREATE is).

<%= button_to "Start Working", projects_tasks_work_intervals_path(@task.project, @task), :method => :post, :remote => true %>

I guess you already have a create action in the controller so you could catch the project and the task with params[:project_id] and params[:task_id], and create a new work interval setting the beginning with Time.now.

If you want to signal the user that it's saved, you could render a create.js.erb and put some javascript code in there that will be shown after the request is over.

To render out that piece of javascript code you will have to have a respond_to block in your action:

def create
    ..
    respond_to do |format|
      format.html
      format.js
    end
end
Zippie
  • 5,657
  • 6
  • 28
  • 44