How to iterate ActiveRecord Attributes, including attr_accessor methods
You can't really solve this. You can approximate a hack, but it's not something that will ever work nicely.
model.attribute_names
should get you all the ActiveRecord ones, but the attr_accessor
fields are not fields. They are just ordinary ruby methods, and the only way to get them is with model.instance_methods
.
Idea 1
You could do model.attribute_names + model.instance_methods
, but then you'd have to filter out all your other normal ruby methods initialize, save
, etc which would be impractical.
To help filter the instance_methods
you could match them up against model.instance_variables
(you'd have to account for the @
sign in the instance variables manually), but the problem with this is that instance variables don't actually exist at all until they are first assigned.
Idea 2
In your environment.rb
, before anything else ever gets loaded, define your own self.attr_accessor
in ActiveRecord::Base
. This could then wrap the underlying attr_accessor
but also save the attribute names to a private list. Then you'd be able to pull out of this list later on. However I'd advise against this... monkey-patching core language facilities like attr_accessor
is guaranteed to bring you a lot of pain.
Idea 3
Define your own custom_attr_accessor
in ActiveRecord::Base
, which does the same thing as Idea 2, and use it in your code where you want to be able to retrieve the attribute names. This would be safe as you won't be clobbering the built-in attr_accessor
method any more, but you'll have to change all your code to use custom_attr_accessor
where neccessary
I guess in summary, what are you trying to do that needs to know about all the attr_accessor
fields? Try look at your problem from a different angle if you can.
How do you output all attributes including attr_accessor attributes?
I don't believe it what you're trying to do is easily possible to do.
See this question:
How to iterate ActiveRecord Attributes, including attr_accessor methods
Looping over attributes of object of a Non-Active-Record-Model
This is the best way I found
item=self.instance_values.symbolize_keys
item.each do |k,v|
...
..
end
There is a code to show it's usage here (look at the update in the question itself) - Grouping via an element in hash
Accessing attr_accessor attributes with variable
you can use
week.send("#{dayname}=", schedule.day == dayname_index ? "Open" : "Closed")
Or you can work with it like instance_variables
week.instance_variable_set("@#{dayname}", schedule.day == dayname_index ? "Open" : "Closed")
how to access attr_accessor in rails model using `attribute_names` method
First of all if you don't know difference b/w attr_acessabe and attr_accessor look at
How to iterate ActiveRecord Attributes, including attr_accessor methods
you can add attr_accessor if you don't an attribute to save in database then add that att_accessor to attr_accessable :)
attr_accessor :color
attr_accessible :color
now
User.accessible_attributes # => ["color"], but beware that you have lost all other attribute you need to add those too if you want to enable mass assignment.
attr_accessible :color,:first_name,:blah,:blah...
Loop through all public attributes in a model
You probably have more allowed attributes than disallowed, so I would create an array of protected attribute names and ignore those when looping through the attributes.
protected_attributes = %w(password salt confirmation_token)
user.attributes.each do |name, value|
unless protected_attributes.include?(name)
something(name, value)
end
end
How to get calculated value in hash (attr_accessor) within ActiveRecord query in rails 4?
I would simply define a method that returns the record as a hash. It uses the attributes
method from ActiveRecord and manually adds the calculated attribute to the hash:
class Task < ActiveRecord::Base
attr_reader :overall_rating
def overall_rating
# returns calculated value, the following is a simple example of a calculation
id + 100
end
def to_h
attributes.merge("overall_rating" => overall_rating)
end
end
Also note that I changed attr_accessor
to attr_reader
as you probably don't want to have a setter defined for the calculated value.
Example:
t = Task.find(5)
t.to_h
# => { "id" => 5, "overall_rating" => 105 }
Rails - attr_accessor :- read the attribute value instead of the function overriding it
attr_accessor
defines a instance variable and a method to access it (read/write).
So the easy way is to write:
def open_ledger_account
create_ledger_account!(opening_balance: @opening_balance)
end
The read_attribute
would only work if opening_balance
was an attribute in the database on Customer
.
ruby on rail - problem with attr_accessor in model
attr_accessor is a class level method. You are trying to use it on an instance level.
Try cattr_accessor
instead. Although you dont need an attr_accessor
orcattr_accessor
to access attributes of anActiveRecord::Base
model that are defined in the schema.
====> EDIT <==== Corrected Answer Below
Disregard the advice above. It's not accurate. Im leaving it for reference. The reason you are getting the undefined method: name
error is because you have set an attr_accessor
on a model that already has a getter set dynamically via ActiveRecord::Base
.
Setting attr_accessor
on an attribute of an ActiveRecord::Base
models DB column causes some sort of conflict. When you remove the attr_accessor
method and instead add whats supposed to be its exact equivalent...
def name
name
end
and then try to call that you get an infinitely recursive looping of your call because the .name
getter method we defined above is calling itself and not accessing the ActiveRecord getter method that actually pulls data from your DB.
Im guessing that somehow active_record model classes will just throw you an undefined method
error rather than make the recursive call that ends in a stack level too deep
error.
However since you arent getting a stack too deep
error my next guess is that the attr_accessor
you defined overrides the dynamically created ActiveRecord::Base
getter while rails is still attempting to access the overridden method ( which dosnt exist anymore ). Possibly resulting in the undefined method 'name'
error.
But...
When you add your own getter method this way... then it works...
def name
super
end
this is because with super
your class is just inheriting the behavior of its dynamically defined ActiveRecord::Base
getter method. You can test this by adding...
def name
super
'Foo'
end
And when you call @model.name
you'll see that Foo
is returned. Remove the 'Foo' from the method and what you have being returned is a super
call to the dynamically created ActiveRecord::Base
getter method.
Im open to edits and input on this answer. This is my logical conclusion from testing in my console and doing some reading.
When to use attr_accessor
Also, to answer your question further about when to use attr_accessor
...
You would use this when you want to create and store information that is business-logic as well as model related, and only lasts for the duration of the request/instance life cycle.
For example raw passwords ( although I cringe at anyone manipulating raw passwords )
or something like...
@stock.current_price
where @stock
is a ActiveRecord::Base
object but .current_price
is calculated or retrieved from an API upon instantiation of the @stock
object because it doesn't make sense to persist and retrieve from the DB an ever changing value such as the price of a stock at any given point in time.
Related Topics
Ruby SQLite3 Installation SQLite3_Libversion_Number() MACos Sierra
Welcome/Home Page in Ruby on Rails - Best Practice
Removing All Empty Elements from a Hash/Yaml
What Does 'If _File_ == $0' Mean in Ruby
Ruby CSV - Get Current Line/Row Number
Add Nullable Foreign Key in Rails
What's the Difference Between Gets.Chomp() VS. Stdin.Gets.Chomp()
Can Rails Migrations Be Used to Convert Data
Digital Signature Verification with Openssl
How to Add Migration with Multiple References to the Same Model in One Table? Ruby/Rails
Base64 Photo and Paperclip -Rails
How to Sort a Ruby Hash by Number Value
How to Suppress Rails Console/Irb Outputs
Error Installing Nokogiri: Failed to Build Gem Native Extension & Libiconv Is Missing (Osx)
Setting Elastic Search Limit to "Unlimited"
Unexpected Return (Localjumperror)
Finding Out Current Index in Each Loop (Ruby)
Error Installing Nokogiri on Bundle Install But Already Installed