Removing or overriding an ActiveRecord validation added by a superclass or mixin
I ended up "solving" the problem with the following hack:
- look for an error on the
:email
attribute of type:taken
- check if the email is unique for this account (which is the validation I wanted to do)
- remove the error if the email is unique for this account.
Sounds reasonable until you read the code and discover how I remove an error. ActiveRecord::Errors
has no methods to remove errors once added, so I have to grab hold of it's internals and do it myself. Super duper mega ugly.
This is the code:
def validate
super
remove_spurious_email_taken_error!(errors)
end
def remove_spurious_email_taken_error!(errors)
errors.each_error do |attribute, error|
if error.attribute == :email && error.type == :taken && email_unique_for_account?
errors_hash = errors.instance_variable_get(:@errors)
if Array == errors_hash[attribute] && errors_hash[attribute].size > 1
errors_hash[attribute].delete_at(errors_hash[attribute].index(error))
else
errors_hash.delete(attribute)
end
end
end
end
def email_unique_for_account?
match = account.users.find_by_email(email)
match.nil? or match == self
end
If anyone knows of a better way, I would be very grateful.
Overriding routes in the Clearance gem
Overriding the layouts is simpler than this: See: https://github.com/thoughtbot/clearance#overriding-layouts
Clearance::PasswordsController.layout 'my_passwords_layout'
Clearance::SessionsController.layout 'my_sessions_layout'
Clearance::UsersController.layout 'my_admin_layout'
Access previous value of association on record update
Could you use ActiveModel::Dirty
? Something like this:
def Event < ActiveRecord::Base
validates :no_invitees_removed
def no_invitees_removed
if invitees.changed? && (invitees - invitees_was).present?
# ... add an error or re-add the missing invitees
end
end
end
Edit: I didn't notice that the OP already discounted ActiveModel::Dirty
since it doesn't work on associations. My bad.
Another possibility is overriding the invited_user_ids=
method to append the existing user IDs to the given array:
class Event < ActiveRecord::Base
# ...
def invited_user_ids_with_guard=(ids)
self.invited_user_ids_without_guard = self.invited_user_ids.concat(ids).uniq
end
alias_method_chain :invited_user_ids=, :guard
end
This should still work for you since update_attributes
ultimately calls the individual attribute=
methods.
Edit: @corsen asked in a comment why I used alias_method_chain
instead of super
in this example.
Calling super
only works when you're overriding a method that's defined further up the inheritance chain. Mixing in a module or inheriting from another class provides a means to do this. That module or class doesn't directly "add" methods to the deriving class. Instead, it inserts itself in that class's inheritance chain. Then you can redefine methods in the deriving class without destroying the original definition of the methods (because they're still in the superclass/module).
In this case, invited_user_ids
is not defined on any ancestor of Event
. It's defined through metaprogramming directly on the Event
class as a part of ActiveRecord. Calling super
within invited_user_ids
will result in a NoMethodError
because it has no superclass definition, and redefining the method loses its original definition. So alias_method_chain
is really the simplest way to acheive super
-like behavior in this situation.
Sometimes alias_method_chain
is overkill and pollutes your namespace and makes it hard to follow a stack trace. But sometimes it's the best way to change the behavior of a method without losing the original behavior. You just need to understand the difference in order to know which is appropriate.
Prevent STI when inheriting from an ActiveRecord model
You can achieve this by disabling the inheritance_column
for the model, like so:
class AnotherSection < Section
# disable STI
self.inheritance_column = :_type_disabled
end
SharePoint Custom Page-Library & PageLayout
I would like to comment on one thing. Looks like IgnoreIfAlreadyExists="TRUE" is not working properly refer to this link, may be reverting the value to FALSE should help.
<File Url="CustomPage.aspx" Type="GhostableInLibrary" IgnoreIfAlreadyExists="TRUE" >
Related Topics
Why Don't Numbers Support .Dup
How to Upload a Text File and Parse Contents into Database in Ror
How to Batch Convert Mp4 Files to Ogg with Ffmpeg Using a Bash Command or Ruby
Rails Fastercsv "Unquoted Fields Do Not Allow \R or \N"
What Is the Standalone Splat Operator (*) Used for in Ruby
Rails Routes: Wrong Singular for Resources
Enable Dropping a File Onto a Ruby Script
Generate Nested Hashes from Strings and Deep Merging in Ruby
Error Using PHPstorm's SASS File Watcher
How to Convert Any Method to Infix Operator in Ruby
How to Make Id a Random 8 Digit Alphanumeric in Rails
Calendar Events Notification Not Received on Server
How to Rescue from a 'Require': No Such File to Load in Ruby
Is There a Difference Between :: and . When Calling Class Methods in Ruby