Skip to content

Instantly share code, notes, and snippets.

@telagraphic
Created September 29, 2012 19:37
Show Gist options
  • Save telagraphic/3805028 to your computer and use it in GitHub Desktop.
Save telagraphic/3805028 to your computer and use it in GitHub Desktop.
Devise Set-Up
class ActionStepsController < ApplicationController
def create
@project = current_user.projects.find(params[:project_id]) # project.rb has a belongs_to :user and user_id column
@sub_project = @project.sub_projects.find(params[:sub_project_id])
@action = @sub_project.action_steps.build(params[:action_step])
if @action.save
redirect_to [current_user, @project, @sub_project]
else
render "sub_projects/show"
end
end
def destroy
@project = current_user.projects.find(params[:project_id])
@sub_project = @project.sub_projects.find(params[:sub_project_id])
@action = @sub_project.action_steps.find(params[:id])
@action.destroy
redirect_to [current_user, @project, @sub_project]
end
end
class User < ActiveRecord::Base
has_many :days
has_many :projects
end
class Day < ActiveRecord::Base
belongs_to :user
has_many :status_updates, :dependent => :destroy
has_one :behavior, :dependent => :destroy
end
class Behavior < ActiveRecord::Base
belongs_to :day
end
class StatusUpdate < ActiveRecord::Base
belongs_to :day
attr_accessible :energy, :mood, :status
end
class Project < ActiveRecord::Base
belongs_to :user
has_many :sub_projects, :dependent => :destroy
end
class SubProject < ActiveRecord::Base
belongs_to :project
has_many :action_steps
end
class ActionStep < ActiveRecord::Base
belongs_to :sub_project
end
class User < ActiveRecord::Base
has_many :days
has_many :projects
end
class Day < ActiveRecord::Base
belongs_to :user
has_many :status_updates, :dependent => :destroy
has_one :behavior, :dependent => :destroy
end
class Behavior < ActiveRecord::Base
belongs_to :day
end
class StatusUpdate < ActiveRecord::Base
belongs_to :day
attr_accessible :energy, :mood, :status
end
class Project < ActiveRecord::Base
belongs_to :user
has_many :sub_projects, :dependent => :destroy
end
class SubProject < ActiveRecord::Base
belongs_to :project
has_many :action_steps
end
class ActionStep < ActiveRecord::Base
belongs_to :sub_project
end
So basically for each of my resources, I want them to be associated with their own user,
so they can only be CRUD-ed by that user.
I keep thinking that I have to write my routes like this, including the :users at the top:
resources :users do
resources :projects do
resources :sub_projects do
resources :action_steps
end
end
end
which produces way long routes like:
/users/:user_id/projects/:project_id/sub_projects/:sub_project_id/action_steps(.:format)
But that is not really necessary to make the association...
because in my controller is where I set up the association.
Correct?
The current_user will associate that resource with it automatically, as long as I have a
foreign key on the nested resource right?
def create
@project = current_user.projects.find(params[:project_id]) # project.rb has belongs_to :user and user_id column
@sub_project = @project.sub_projects.find(params[:sub_project_id]) # sub_project.rb does not have user_id column
@action = @sub_project.action_steps.build(params[:action_step]) # action_step.rb doesn't either
if @action.save
redirect_to [current_user, @project, @sub_project]
else
render "sub_projects/show"
end
end
The interesting thing is that in my sub_project.rb and action_step.rb models I don't associate them
to the user with a belongs_to :user method, but yet they still are associated with that current user
because of the association on the @project line. So when I show them all with an index or show action,
I still only get the sub_projects and action_steps that belong to that user.
So the relationship set here:
@project = current_user.projects.find(params[:project_id])
falls through to the other associations here:
@sub_project = @project.sub_projects.find(params[:sub_project_id])
@action = @sub_project.action_steps.build(params[:action_step])
Even without a user_id column on either of these two tables?
It's feels like I should a foreign key column to them to make it correct? Right?
If I wanted to get all the action steps associated to user 3, then I would have to associate action_steps to users
in order to write code like this:
@actions = current_user.action_steps
I hope this makes some sense?
As I was writing this, I realized/remembered that the routes is just for URL's and
the helper methods, not so much for associating the user to projects. current_user does this "behind the scenes"
without it showing up in the URL.
LifeUlator::Application.routes.draw do
devise_for :users
resources :users do
resources :days do
resources :status_updates
resources :behaviors
end
resources :projects do
resources :sub_projects do
resources :action_steps
end
end
end
root :to => "days#index"
end
It's "recommended" to write nested resources like this instead, right?
devise_for :users
resources :users
resources :days do
resources :behavior
resources :status_updates
end
resources :projects do
resources :sub_projects
end
resources :sub_projects do
resources :action_steps
end
It's "recommended" to write nested resources like this instead, right?
devise_for :users
resources :users
resources :days do
resources :behavior
resources :status_updates
end
resources :projects do
resources :sub_projects
end
resources :sub_projects do
resources :action_steps
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment