What is the ActiveModel method attribute _was used for?
That is a part of ActiveModel::Dirty
You can see it here https://github.com/rails/rails/blob/af64ac4e5ce8406137d5520fa88e8f652ab703e9/activemodel/lib/active_model/dirty.rb#L146
Example
person = Person.find_by_name('Uncle Bob')
person.changed? # => false
Change the name:
person.name = 'Bob'
person.changed? # => true
person.name_changed? # => true
#method _was return prev attribute value
person.name_was # => 'Uncle Bob'
person.name_change # => ['Uncle Bob', 'Bob']
person.name = 'Bill'
person.name_change # => ['Uncle Bob', 'Bill']
ActiveModel attributes
I've managed to solve problem with this code:
class PurchaseForm
include ActiveModel::Validations
include ActiveModel::Conversion
extend ActiveModel::Naming
attr_accessor :attributes,
:name,
:surname,
:email
validates_presence_of :name
validates_format_of :email, :with => /^[-a-z0-9_+\.]+\@([-a-z0-9]+\.)+[a-z0-9]{2,4}$/i
def initialize(attributes = {})
@attributes = attributes
end
def persisted?
false
end
end
Methods vs Attributes Rails
To answer the part I think I understand: yes, an attribute on a model is quite different than a method.
Take, for example, a User model, a Users controller, and one of its corresponding views. Let's pretend the User model itself contains first_name
, last_name
, and email
properties:
class User < ActiveRecord::Base
#Ensure presence of the following before saving model
validates_presence_of :first_name, :last_name, :email
#Verify unique email
validates_uniqueness_of :email
#Here's our lone User method...poor guy
def admin?
self.company_members.where('? = ANY (company_members.roles)', Role::ADMIN).any?
end
end
When you get around to working with an instance of that model in your controller, it'll look something like this:
class UsersController < ApplicationController
def index
#Let's just grab a random user
@user = User.find(1)
end
end
Finally, in your view, your properties (attributes) can be accessed in the following way:
####views/users/index.html.haml####
.random-class
= "You're logged in as #{@user.first_name}!"
But we can also call User methods in the view as well. Continuing off our last example, we could add something like this:
####views/users/index.html.haml####
.random-class
= "You're logged in as #{@user.first_name}!"
- if @user.admin?
= 'Oh my gosh, our freaking User method worked!'
So in short, you're correct in that properties and methods are very different, although they look similar at times.
Lastly, it's worth pointing out that instance methods are just that: methods called on instances of a class, whereas class methods are called on an actual model object, and not a singular instance of that model object. Here's a great link to learn more about the differences.
Hope this helps!
Detecting if value of attribute changed during last update doesnt work with Active Model Dirty
.update
also saves the model after updating it's data, therefore resetting the dirty-values. Try using .assign_attributes
. It will just assign the attributes, then you can check for changes, and finally remember to save the model.
ActiveModel equivalent for ActiveRecord has_attribute?
Based on the code example above, you don't need to use an ActiveModel method similar to has_attribute?
at all--you can simply fall back to plain ol' Ruby:
def initialize(attributes = {})
attributes.each do |name, value|
send("#{name}=", value) if respond_to?("#{name}=")
end
end
This will only assign the attribute if it has been initiated with attr_accessor
.
Is it better practice to use attribute_name or self.attribute_name when accessing within model
Camp 1: Convention over configuration. Also, self.first_name
will not work for private accessors.
Camp 2: You know what's what at a glance, whereas you might forget what methods you have without the explicit receiver.
In the end, it's an opinion question, so I'm voting to close. However, food for thought:
bbatsov style guide:
Avoid
self
where not required. (It is only required when calling a self write accessor.)
GitHub style guide (based on bbatsov style guide):
Avoid explicit use of
self
as the recipient of internal class or instance messages unless to specify a method shadowed by a variable.
Rails model #attributes method shows gem inserted association as model attribute
The gem is causing this, since you upgraded 2 major versions a lot of changes were made. Possibly this line is causing it https://github.com/mbleigh/acts-as-taggable-on/blob/950c01072b7ab6227d74dc0d0b112f0135281fc2/lib/acts_as_taggable_on/taggable/core.rb#L42.
Your options are to either change your code to support this change or try running the older gem version if it supports Rails 5.
Related Topics
Ruby: "&& Return" VS "And Return"
Ruby $Stdin.Gets Without Showing Chars on Screen
Ruby: How to Generate CSV Files That Has Excel-Friendly Encoding
How to Split String into Only Two Parts with a Given Character in Ruby
Why Is Ruby's Date Class Automatically Loaded But Datetime Is Not
Heroku App Fails to Start - 'Require': No Such File to Load -- Sinatratestapp (Loaderror)
Rails 3: Call Functions Inside Controllers
Do Ruby 1.8 and 1.9 Have the Same Hash Code for a String
Ruby: Write Escaped String to Yaml
How to Recursively Require All Files in a Directory in Ruby
Rails: Why Images Are Not Showing in My Rails Basic App
"Errno::Eaccess...Permission Denied" Running Compass Watch
How to Ignore Multiline Comments in SASS