Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Should I use class method or instance method, and why?

In my Rails app, when creating a business I have a form that has the following field:

   <%= check_box_tag(:default_company) %> 
   <%= label_tag(:default_company, "Set Company as Default") %>

Essentially when I create a business, if they check this box, I need it to run something like the following code:

def set_default_company(company, user)
  exists = DefaultCompany.find(user.id)
  if exists
    exists.update_attributes(company: company)
  else  
    DefaultCompany.create(company: company, user: user)
  end
end

While learning, I would usually do that stuff in my controller but i'm trying to follow best practices and use a fat model, skinny controller, so I'm wanting to use logic like this:

def create
  @company = Company.new(params[:company])

  if @company.save
    if params[:default_company]
      Company.set_default_company(@company.id, current_user.id,)
    end
    flash[:notice] = "Company was successfully created."
    redirect_to @company
  else
    redirect_to new_company_path
  end
end

Here is where I am getting confused on whether to use a class method or an instance method, to call set_default_company. They both seem like they would work and I can't see a benefit to one or the other.

In addition to giving me any information as to which method to use, if someone could show me a brief implementation of writing that as a class method vs. instance method it may give me a better understanding as to why.

Here is how I would write them:

def self.set_default_company(company, user)
  # Logic here
end

def set_default_company(company, user)
  # Logic here
end

Writing them that way I don't see a benefit to either.

like image 258
ruevaughn Avatar asked Jul 25 '12 17:07

ruevaughn


People also ask

When should you use a class method?

You can use class methods for any methods that are not bound to a specific instance but the class. In practice, you often use class methods for methods that create an instance of the class. When a method creates an instance of the class and returns it, the method is called a factory method.

Why do we need instance method?

Since java is an object-oriented programming language, we need to write a method inside some classes. The important points regarding instance variables are: Instance methods can access instance variables and instance methods directly and undeviatingly.

Why do we use class method?

Class methods are used when we are dealing with factory methods. Factory methods are those methods that return a class object for different use cases. Thus, factory methods create concrete implementations of a common interface. The class method can be called using ClassName.


1 Answers

As their name suggests, instance methods on a model should be used for logic/operations that relate to a specific instance of a user (the one on which the method is called.) So you could think of setting the default company for a user as an instance method on User. Class methods are for things which don't operate on an individual instance of a model or for cases where you don't have the instance available to you. e.g. you might have a class method to tidy up your database such as User.purge_expired_users which would not apply to an individual user object.

e.g.

class User
  def set_default_company(company)
    exists = DefaultCompany.find(self.id)
    if exists
      exists.update_attributes(company: company)
    else  
      DefaultCompany.create(company: company, user: self)
    end
  end
end

then your controller method would look like:

def create
  @company = Company.new(params[:company])

  if @company.save
    if params[:default_company]
      current_user.set_default_company @company
    end
    flash[:notice] = "Company was successfully created."
    redirect_to @company
  else
    redirect_to new_company_path
  end
end

Alternatively, you could think of the relationship from the other perspective and put an instance method on Company e.g. company.set_as_default_for(user).

like image 136
mikej Avatar answered Oct 06 '22 14:10

mikej