Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ruby on Rails - Creating and Using a Custom Method

I am rather new to Rails, and would greatly appreciate any bit of help. I have created the following method:

  def name_fix
    name = self.split
    mod_name = []
    name.each do |n|
      n.split("")
      if n[0]
        n.upcase
      else
        n.downcase
      end
      mod_name.push(n)
    end
    mod_name.join
  end

I would like to use this method in my Controller as such:

def create
  @patient = Patient.new(params[:patient])
  @patient.name = params[:params][:name].name_fix
  if @patient.save
    redirect_to patients_path
  else
    render :new
  end
end

How can I go about accomplishing this? Will this method reside within my Model or Controller? Previously, I've run into an undefined method error.

Note: I'm sure that there is a way to better write my code. I am grateful for help with that as well.

like image 749
M.M. Avatar asked Oct 31 '22 17:10

M.M.


1 Answers

#app/models/patient.rb
class Patient < ActiveRecord::Base

   protected

   def name=(value)
      mod_name = []
      value.split.each do |n|
         n.split("")
         type = n[0] ? "up" : "down"
         n.send("#{type}case")
         mod_name.push(n)
      end
      @name = mod_name.join
   end
end

#app/controllers/patients_controller.rb
class PatientsController < ApplicationController
   def create
      @patient = Patient.new patient_params
      @patient.save ? redirect_to(patients_path) : render(:new)
  end

  private

  def patient_params
     params.require(:patient).permit(:name)
  end
end

What you're doing is trying to override the setter method, which can be done using the above code. Much more efficient and out of the way.


I have created the following method

Since you're new, let me explain something else.

It is important to note where you're using this method.

You've currently put it in the model, which means you'll have to call it to manipulate some attribute / functionality of any object created with said model.

--

Models - in Rails - build the objects which populate your app. Ruby is an object orientated language, which means that every element of your program should revolve around data objects in some degree.

enter image description here

As you can see above, the method of building objects in your system is really about invoking classes. These classes contain methods which can be called, either at class level (IE invoking the class through the method), or at instance level (IE calling a method on an already invoked object).

This is where you get "class" methods (Model.method) and "instance" methods (@model.method) from:

#app/models/patient.rb
class Patient < ActiveRecord::Base
   def explode
      #this is an instance method
      puts "Instance Explode"
   end

   def self.explode
      #this is a class method
      puts "Exploded"
   end
end

Thus you can call the following:

@patient = Patient.find params[:id]
@patient.explode #-> "Instance explode"

Patient.explode #-> "Exploded"

--

This is important because it gives you a strict framework of where you should, and shouldn't use methods in your models.

It explains why you have controllers & helpers, and allows you to formulate the best way to structure your application as to get the most out of the least code.

For example...

Your use of @patient.name = params[:params][:name].name_fix is incorrect.

It's wrong because you're calling the instance method .name_fix on a piece of data totally unrelated to your model. If you wanted to use .name_fix in a general sense like this, you'd probably use a helper:

#app/helpers/patients_helper.rb
class PatientsHelper
   def name_fix value
      # stuff here
   end
end

#app/controllers/patients_controller.rb
class PatientsController < ApplicationController
   def create
      @patient.name = name_fix params[:patient][:name]
   end
end

Since you're using the method to populate the .name attribute of your model, it makes sense to override the name= setter. This will not only provide added functionality, but is much smoother and efficient than any other way.

like image 155
Richard Peck Avatar answered Nov 15 '22 06:11

Richard Peck