Excuse me for the noob question.I am a newbie to ruby and rails and Needed some help in Understanding the attr_accessor which I have come across in the code
create_table "pets", force: :cascade do |t|
t.string "name"
t.string "colour"
t.string "owner_name"
t.text "identifying_characteristics"
t.text "special_instructions"
t.datetime "created_at"
t.datetime "updated_at"
t.string "email"
t.string "password"
end
model
class Pet < ActiveRecord::Base
has_many :pet_photos
cattr_accessor :form_steps do
%w(identity characteristics instructions)
end
attr_accessor :form_step
validates :email, presence: true
validates :name, :owner_name, presence: true, if: -> { required_for_step?(:identity) }
validates :identifying_characteristics, :colour, presence: true, if: -> { required_for_step?(:characteristics) }
validates :special_instructions, presence: true, if: -> { required_for_step?(:instructions) }
def required_for_step?(step)
return true if form_step.nil?
return true if self.form_steps.index(step.to_s) <= self.form_steps.index(form_step)
end
end
and
class Pet::StepsController < ApplicationController
include Wicked::Wizard
steps *Pet.form_steps
def show
@pet = Pet.find(params[:pet_id])
render_wizard
end
def update
@pet = Pet.find(params[:pet_id])
@pet.update(pet_params(step))
if params[:images]
params[:images].each do |image|
@pet.pet_photos.create(image: image)
end
end
render_wizard @pet
end
private
def pet_params(step)
permitted_attributes = case step
when "identity"
[:name, :owner_name]
when "characteristics"
[:colour, :identifying_characteristics]
when "instructions"
[:special_instructions]
end
params.require(:pet).permit(permitted_attributes).merge(form_step: step)
end
end
routes
PetThing::Application.routes.draw do
resources :pets, only: [:new, :create, :index, :destroy] do
resources :steps, only: [:show, :update], controller: 'pet/steps'
end
root to: 'pets#index'
1) what I all only know about attr_accessor
is, it nothing more than a getter/setter for an object.I do not have a form_step
as an attribute of my Pet Model(pets table).But in the model, there is attr_accessor :form_step
.How is getter/setter generated to :form_step
?
2) Is :form_step
an object of Pet class?
I am not totally understanding the usage of attr_accessor
method in Rails model class.
3) Kindly explain me a scenario where I must generate getter/setter for Model attributes (pets table attributes or fields)
eg: attr_accessor :name
attr_accessor :colour
..etc
when do we use attr_accessor
for model attributes or fields?
Lets starts with OOPs, basically class
is template which defines properties and behavior of its instances i.e. objects.
The rails model also a ruby class. Its properties are being defined by attr_accessor
and behaviors are defined by static and instance methods
.
Consider a class with attr_accessor
class Animal
//defines animal properties
attr_accessor :legs
//defines animal behavior
def talk
end
end
and without attr_accessor
class Animal
//defines animal properties
//getter
def legs
@legs
end
//setter
def legs=(value)
@legs = value
end
//defines animal behavior
def talk
end
end
Both representations are exactly same. The attr_accessor
automatically add getter and setter for us and makes the life of developer easier.
Lets answer you questions
Ruby attr_accessor
automatically adds these for you as explained earlier.
form_step
its a attribute of Pet class
and can be accessed as petObj.form_step
.
If table is associated/mapped with Model, then you don't have to define columns in tables as attr_accessor
, Rails automatically takes care for you. If field or attribute not exists in table, then you need to manually define it as attr_accessor
in Model
.
I hope this answers your question.
Part of the Rails' magic is that when you have a class Pet and a table pets, you get the accessors for all the columns in the table for free. It's as if you've declared attr-accessor
for all of them, only you don't need to.
In your example, #form_step
is not created in the table. But it is declared using attr_accessor
. It works just like plain old ruby. This gives you a getter/setter (answer to your Q1).
It's an instance method of Pet class. You call it on a Pet object, like Pet.new.form_step = 5
(answer to Q2).
But you can't persist whatever value you assign to #form_step
to db. So the answer to Q3 is that you usually do this when you need to pass some messages (i.e. call methods) between your objects, but you don't need to persist them to db.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With