To my knowledge, the new default in Rails 5 requires belongs_to associations to be present. I made a model with this association, but the problem is I don't get presence validation error when the associated field is empty. Instead I get a database Null Validation error since I set the _id column not to be null. (PG::NotNullViolation because I use Postgres)
Is this behaviour normal? I mean shouldn't I get the rails error only?
BTW, when I add presence validation for the field, it works as I expected.
According to the issue re weird behaviour of config belongs_to_required_by_default, it seems like one of your other gems intervenes in ActiveRecord::Base and causes the bug.
One of workarounds to the issue is to move the line
config.active_record.belongs_to_required_by_default = true
from initializers directly into application.rb.
This worked for me smoothly.
New Rails 5 applications come with a new initializer in
config/initializers/active_record_belongs_to_required_by_default.rb
If you upgraded a Rails 4 application or created your application with a beta version of Rails 5, then that file might be missing.
The configuration in that file enables the feature in question:
# Be sure to restart your server when you modify this file.
# Require `belongs_to` associations by default. This is a new Rails 5.0
# default, so it is introduced as a configuration option to ensure that apps
# made on earlier versions of Rails are not affected when upgrading.
Rails.application.config.active_record.belongs_to_required_by_default = true
Please check how belongs_to_required_by_default is configured in your application.
I faced with same problem.
You can move
config.active_record.belongs_to_required_by_default = false
to config/environments/needed_environment.rb or to config/application.rb
Helped for me!
Related
I have a rails engine which encapsulates a piece of my application's funtionality. I have a bunch of models in the engine, which have various belongs_to associations defined. As of rails 5 these associations are supposed to be required by default, unless optional: true is specified in the definition.
I’m still able to create instances of the models without any validation errors. I haven’t specified optional: true on any of the associations, nor is the config optionconfig.active_record.belongs_to_required_by_default set anywhere. Besides, it was removed in rails 6 anyway.
I can't think of any reason the model instances would not fail validation. I would expect any instances of any model with an undefined belongs_to association would be invalid and raise an error. Why would these records pass validation?
I found my problem, thanks to #MatthiasWinkelmann for the tip. It turns out my engine was not calling load_defaults at all. I needed to add the following to spec/dummy/config/application.rb:
module Dummy
class Application < Rails::Application
config.load_defaults Rails::VERSION::STRING.to_f
... etc ....
end
end
here is an article containing more explanation:
An upgraded Rails gem does not upgrade your Rails configuration
I probably would have done better to mention in my question that I'm in the process of upgrading my application from Rails 4.2 to 6.1. The change was introduced in Rails 5.
I'm working on upgrading a Ruby 2.2.2 (Rails 4.1) app to Ruby 2.5.7 (Rails 5.2) and for a couple of models I'm getting some errors
From searching around, it sounds like there are some generic activerecord validation rules / messages? The messages are:
Status is invalid
User is invalid`
I am a novice at best with Ruby - so any suggestions on the best way to work through this error are appreciated!
In Rails 5, whenever a belongs_to association is defined, it is required to have the associated record present by default. That means, compared to Rails 4, each belongs_to :foo association basically adds internally a validate :foo, presence: true to the code too.
You have two choices:
Follow the new Ruby on Rails conventions and fix your tests by adding all required associated objects to the models.
Switch back to the old behavior for these kinds of associations by adding , optional: true to each belongs_to :foo line in your code.
There is actually the third option to switch off this behavior in the whole application, by adding a line like this to your application.rb
Rails.application.config.active_record.belongs_to_required_by_default = true
But that means your application will not follow Ruby on Rails conventions and defaults anymore and IMHO this ofter leads to problems with a later update.
Therefore my advice is: Fix your tests now and only make those associations optional that are really optional from the user's point of view – this might take a bit longer but causes certainly less trouble in the future.
I'm using the latest version of the Impressionist and Rails Admin gems, and wondering if anyone could shed some light on an annoying conflict I'm experiencing. The problem is roughly documented here - https://github.com/sferik/rails_admin/issues/1315, yet the vaguely described solution is not working for me. When I have the line is_impressionable in my Listing model, I get an error when starting my Rails server with rails s:
...rvm/gems/ruby-2.0.0-p247/gems/activerecord-4.0.2/lib/active_record/dynamic_matchers.rb:22:in `method_missing': undefined local variable or method `is_impressionable' for Listing(no database connection):Class (NameError)
If I first start the server, and then add the 'is_impressionable' line, everything works fine, so the problem only occurs during initialization. I don't fully understand the initialization process, so am not sure how to go about getting this to work.
I have tried moving all my rails_admin model configuration options to their respective models, rather than in the initializer, which had no effect. I also have the following line in my initializer:
config.included_models = [Listing,ListingImage,AllOtherModelsHere...]
I have tried adding single quotes around these model names, which results in the following errors, as described in the github issue here
[RailsAdmin] Could not load model Listing, assuming model is non existing. (undefined local variable or method `is_impressionable' for Listing(no database connection):Class)
Any ideas what else I can try to make these gems work together? I don't want to have to remove the is_impressionable line every time I want to restart the server or generate a migration...
Not sure if the same issue that I had but yet I will post what worked for me just in case someone struggles with this too:
Im on a ruby 2.1.5 project with rails 4.2.0 and among other gems I'm using rails admin.
I run into several weird problems trying to set this up. For instance if I added the is_impressionable call within one of my models for some reason the execution of that file stopped there and I started getting weird errors like any method declared below the is_impressionable failed with undefined error.
So what I end up doing was:
class MyModel < ActiveRecord::Base
include Impressionist::IsImpressionable
is_impressionable
end
So this solved my issue and now i can access #my_model_instance.impression_count as expected.
I changed every occurrence of Klass to 'Klass'.constantize in initializer.
I just spent quite some time trying to resolve a virtual attribute issue in my model. It turned out I'd simply forgotten to add it to attr_accesible in my model. Granted I should have caught it earlier or better should have started the whole endeavor by adding it to attr_accessible in the first place.
To keep this from happening again, is there a configuration setting I can flag to throw an exception on development if I try to mass assign something and validate it when it is protected/inaccessible? I know I can use set config.active_record.whitelist_attributes = true to require whitelist for all but my question is more on an individual attribute basis.
The line above for example does not warn me if I have a model with attr_accessible :name then later add :nickname (virtual or not), and try to mass assign it checking for presence=>true. I want it to warn me that I tried to validate a protected attribute through mass assignment.
Rails 3.2 has a configuration option to raise a ActiveModel::MassAssignmentSecurity::Error in that case
config.active_record.mass_assignment_sanitizer = :strict
See Rails 3.2 release notes and the commit in Rails
Is there a way to have rails raise an error if an attempt is made to mass-assign attributes that aren't allowed by attr_accessible?
This would be handy in development to remind me why my shiny new model isn't working, and also good to log in production in order to detect malicious activity.
I'm using rails 2.3.8 but will probably soon be migrating to 3.
As of Rails 3.2 this no longer requires monkeypatching -- rails provides this behavior now. Put this in development.rb and test.rb:
config.active_record.mass_assignment_sanitizer = :strict
I would suggest something like the Bento project has incorporated into their Rails app.
They create a Rails Initializer under config/initializers/ and then override the appropriate method in the ActiveModel class to raise a MassAssignmentError (within non-production environments).
I am not sure if this would work, but you could write a test to see if your object "respond_to(:unexpected_attr)". You can then tried to force feed it that attr
Alex