4

I've defined an instance variable in my ApplicationController like that:

@team = Team.find(params[:team_id])

Now, in my EventsCreator model I'd like to access @team from above:

class EventsCreator
  # ...

  def team_name
    name = @team.name
    # ...
  end

  # ...
end

With that code I get the following error:

undefined method `name' for nil:NilClass

How should I access instance variables like this from a model? Is there a better way or better practice to do so?


Edit 1:

The event.rb model is the model which contains common information which is also saved in the database:

class Event < ApplicationRecord
  belongs_to :team
  attr_accessor :comment
  ...
end

The events_creator.rb model is kind of an extension to event.rb. It contains some logic e.g. for repeating events:

class EventsCreator
  include ActiveModel::Model
  attr_accessor :beginning, :ending, :repeat_frequency, :repeat_until_date
  ...
end

EventsCreator does not directly create Records in the DB. It just does some logic and saves the data through Event model.

Now without having a direct relation to team.rb I want to be able to access the instance variable @team which is defined in application_controller.rb:

class ApplicationController < ApplicationController::Base
  before_action :set_team_for_nested

  private
  def set_team_for_nested
    @team = Team.find(params[:team_id])
  end
end

My routes.rb file is nesting all routes inside team because I need the team_id for every action:

Rails.application.routes.draw do
  resources :teams do
    resources :events
    get '/events_creator', to: 'events_creator#new', as: 'new_events_creator'
    post '/events_creator', to: 'events_creator#create', as: 'create_events_creator'
  end
end

Now I have no idea how to access the @team instance variable (which I thought is defined for the whole application) from a model. Since I'm quite new to Rails, I might have messed up things, please tell me if there are better ways to achieve the same.

mabu
  • 286
  • 8
  • 26

2 Answers2

2

You will have to pass the team as an argument to your class.

class EventsCreator
  attr_reader :team
  def initialize(team)
    @team = team
  end

  def some_method
    puts team.name
  end
end

# Then in your controller you can do this
def create
  EventsCreator.new(@team)
end

If you plan on including ActiveModel::Model then you can just do

class EventsCreator
  include ActiveModel::Model
  attr_accessor :team

  def some_method
    puts team.name
  end
end

# And then in your controller it's the same thing
def create
  EventsCreator.new(@team)
end
patkoperwas
  • 1,341
  • 10
  • 14
-1

simple

class EventCreator

  ...

  def team_name
    name #will return name of class instance
    #or do something with it
  end
end
marmeladze
  • 6,468
  • 3
  • 24
  • 45
  • 1
    I am not sure how this is an answer and since your *explanation* is "simple" I think you have made it anything but – engineersmnky Aug 31 '17 at 16:32
  • (s)he wants to access an instance property and i've tried to show how to do. what's wrong? -)) – marmeladze Sep 02 '17 at 12:55
  • You simply showed how to call another (undefined) method and/or state a nonexistent local variable. You have no explanation and certainly no instance variables. This in way addresses that actually question – engineersmnky Sep 02 '17 at 14:19
  • you are commenting based on an anachronism. i've posted when question was like that - https://stackoverflow.com/revisions/9dbd5cd7-4c80-428f-9298-4e0805825d73/view-source just realised that it's been edited and evolved to a completely different question. – marmeladze Sep 02 '17 at 23:55