I have Discussions (polymorphic) that belong to Projects, Tasks and Subtasks. Tasks belong to Projects, and Subtasks to Tasks.
I have users connected to Projects via join table called 'synapses'. Synapse model has user_id, project_id and boolean field called :leader which signals if the user has leader (AKA admin) rights.
For a user to close(finish) the discussion, he needs to be a leader of current project or needs to be the creator of that discussion. Here is the 'finish' method in Discussions controller:
33 def finish
34 if current_user.leader? || current_user.discussions.include?(@discussion)
35 @discussion.update_attribute(:finished, true)
36 redirect_to polymorphic_path([@parent, Discussion])
37 flash[:notice] = "Discussion '#{@discussion.name}' finished"
38 else
39 flash[:alert] = 'You must be an admin to do that'
40 end
41 end
Since user model doesn't have leader attribute on itself, I need to find the corresponding synapse between current user and project(which does have leader boolean field, showing if the user can close the discussion). Here is the method I have in application_controller to find the synapse:
9 def find_synapse(user,project)
10 user.synapses.find_by_project_id(project)
11 end
To find the synapse, I need to find the Project. So far I can find the parent of the Discussion, which can be either the Project, Task, or Subtask model.
The way I see it, I need to iterate through parents and than stop when the parent's is of the class Project (for loop?). How to do this? Is this the best way to go about it? BTW, I tried using switch-case (when @parent.class is Task, do this, when class is Project, do that), but seems hackish and I didn't manage it to work anyway.