views:

119

answers:

3

Hi all,

I use inheritance in my model. An event has different types:

Event < activity
Event < training
Event < game

I want to set session data to every event type like

game.user_id = session[:user_id]
training.user_id = session[:user_id]
activity.user_id = session[:user_id]

I want to avoid writing @game.user_id = session[:user_id] , ..., ... in every create method in the controller of activity, game and training

Someone knows how to approach this best.

Thanks

+3  A: 

Perhaps you are looking for a before_filter that resides in your ApplicationController? Then in each controller, you can set the before_filter to run on create actions.

ApplicationController
  def set_user_ids
    game.user_id = session[:user_id]
    training.user_id = session[:user_id]
    activity.user_id = session[:user_id]
  end
  ...
end

OneController < ApplicationController
  before_filter :set_user_ids, :only => [:create]
  ...
end

TwoController < ApplicationController
  before_filter :set_user_ids, :only => [:create]
  ...
end
erik
It's nice that stackoverflow shows you an alert when new answers come in, since I was just typing up the same solution.
Dan McNevin
You can also reduce the code duplication by doing [game, training, activity].each {|event| event.user_id = session[:user_id]}.
Chuck
I also thuoght about putting it in the application controller but I feel this code should be restricted to an event related controller. I would prefer to make a method in the event controller and then call it with a before filter from the other controller. I don't know if this is possible?
Tarscher
A: 

Don't use game.user_id, instead you can do this:

game = current_user.games.build(params[:game])
if game.save
  # do something
else
  # do something else
end

Repeat for your other controllers too!

The associations guide may be helpful too.

Ryan Bigg
When I do game = current_user.games.build(params[:game]) get a NoMethodError (undefined method `games' for #<User:0x40db1c4>):class Game < Event class Event < ActiveRecord::Base belongs_to :userendclass User < ActiveRecord::Base has_many :events endDoesn't seem to work for inheritance?
Tarscher
Because the user model needs to has_many :games too.
Ryan Bigg
A: 

Generally you'll want to use the built-in scoping that Rails provides. Just to flesh out what @Radar already posted:

class ApplicationController < ActionController::Base
  before_filter :find_current_user

  private
    def find_current_user
      @current_user = User.find( session[:user_id] )
    end
end

class EventsController < ApplicationController
  def create
    @event = @current_user.events.build( params[:event] )
    @event.save!
  end
end

This assumes that you have setup the associations in your model:

class User
  has_many :events
end

class Event
  belongs_to :user
end

This is also a rather handy mechanism if you need to restrict what a user can see or edit:

class EventsController < ApplicationController
  def index
    @events = @current_user.events # only fetch current users events
  end

  def update
    @event = @current_user.events.find( params[:id] ) # can't update other user's events
    @event.update_attributes!( params[:event] )
  end
end
CaffeineFueled