Reputation: 6265
When I write ActiveRecord
models in rails I want to make sure that local variables I use in my method will remain local to the scope of the method I write, and I will not be accidentally overwriting model property in future.
For example:
class User < ActiveRecord::Base
after_save :do_something
def do_something
# ... some logic
group = "some value"
# ... more logic
end
end
How do I make sure that if I happen to add group
property to my model in future - my method will not accidentally overwrite it?
I thought about class variables, but it's not what they are for, and I think using them will be a bad practice.
Upvotes: 1
Views: 3733
Reputation: 2364
In ruby you can define local variables and instance variables with the same name.
class Example
@instance = 4
def example_method
@instance += 1
end
def example_2
instance = 0
10.times { instance += 1 }
end
end
e = Example.new
e.example_2 # => 10
e.instance # => 4
e.example_method # => 5
e.instance # => 5
these will not conflict
is returning the local variable which is then destroyed if not used
is setting the instance variable which will save per instance of the class or in this case for active record will save to database.
Also note you can be more explicit when referring to instance variables and say
self.instance
your group
variable inside your do_something
is a local variable and will not cause conflict with @group
which is a instance variable of a higher scope
I have a projects model in my application
class Project < ActiveRecord::Base
VALID_NAME_REGEX = /(\A[\w ]+)/
VALID_URL_REGEX = URI::regexp(["http", "https"])
validates :name, :presence => true,
:uniqueness => true,
:length => {
:maximum => 24
},
:format => {
:with => VALID_NAME_REGEX,
:message => "Only allow numbers letters hyphens and underscores"
}
after_save :test
def test
name = 'bob'
end
end
after setting my model to this and creating a new instance of it on my website I can confirm this will not set my projects name to bob
Upvotes: 1
Reputation: 448
Using a local variable, that is a variable not prefixed by @ or @@ will not cause a namespace collision with future model attributes. Those attributes would have to be referenced in such a way similar to self.group
. You could run into trouble if your code in your model tweaks the class by adding fields or members to the object at runtime, or if you mess with the class definition, but just declaring a local variable in a method will not collide with an instance variable that corresponds to an ORM field.
Additionally, if you've got methods to mutate fields in your model and you try to access them by saying
def getgroup
group
end
this won't work, either. group
in this context is undefined, because it doesn't refer to anything else in the local scope
Upvotes: 1