-
Notifications
You must be signed in to change notification settings - Fork 21.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ActiveRecord belongs_to update foreign_key not validated. #26557
Comments
Can you provide a sample app that mimics the behavior? |
@develop-test1 Based on your given steps, I was not able to figure out how to trace it out properly. It would be good if you provide more details about your association logic for Still, I went further and I tried following steps and it worked as expected. begin
require "bundler/inline"
rescue LoadError => e
$stderr.puts "Bundler version 1.10 or later is required. Please update your Bundler"
raise e
end
gemfile(true) do
source "https://rubygems.org"
# Activate the gem you are reporting the issue against.
gem "activerecord", "5.0.0.rc1"
gem "sqlite3"
end
require "active_record"
require "minitest/autorun"
require "logger"
# Ensure backward compatibility with Minitest 4
Minitest::Test = MiniTest::Unit::TestCase unless defined?(Minitest::Test)
# This connection will do for database-independent bug reports.
ActiveRecord::Base.establish_connection(adapter: "sqlite3", database: ":memory:")
ActiveRecord::Base.logger = Logger.new(STDOUT)
ActiveRecord::Base.belongs_to_required_by_default = true
ActiveRecord::Schema.define do
create_table :authors, force: true do |t|
end
create_table :posts, force: true do |t|
t.integer :author_id
end
end
class Author < ActiveRecord::Base
has_many :posts
end
class Post < ActiveRecord::Base
belongs_to :author
end
class BugTest < Minitest::Test
def test_association_stuff
author= Author.create!
post = Post.create!(author_id: author.id)
assert_raises(ActiveRecord::RecordInvalid) do
post.update!(author_id: 0) # Invalid id which is not present in the database
end
end
end Above test passed successfully. class Post < ActiveRecord::Base
belongs_to :author, optional: true
end Could you check that and let us know? |
Thank you @mechanicles for quick response. I've checked and my model and I can confirm that it doesn't have However if I set-up up with
in fact i get expected behaviour: However seeting That way I could only allow for |
Moreover it appears that changing (as described here: #18937): |
Based on this: http://blog.bigbinary.com/2016/02/15/rails-5-makes-belong-to-association-required-by-default.html My model behaves like Rails 4 model, however I'm using Rails 5. Any ideas? |
The blog post is old before we introduced https://github.com/rails/rails/blob/master/railties/lib/rails/generators/rails/app/templates/config/initializers/new_framework_defaults.rb.tt I think if you have updated the app from Rails 4 to Rails 5, then you have Rails.application.config.active_record.belongs_to_required_by_default = false in your config/initializers/new_framework_defaults.rb which is why you have Rails 4 behavior. If you want the Rails 5 behavior, then change it to Rails.application.config.active_record.belongs_to_required_by_default = true As such we need more details on what is exactly not working in this issue. please use http://edgeguides.rubyonrails.org/contributing_to_ruby_on_rails.html#create-an-executable-test-case to create an bug test case or upload a sample application to github reproducing the issue. Thanks! |
Ok, I've found out what was the source of this behaviour. It appears that: Causes this behavior. Removing this gem brought back expected behavior. |
Great, I am closing this issue as it is not related to Rails. Thanks for confirming! |
Hold on, removing this gem didn't fix the problem completely. Let me double check just to be 100% sure. |
Ok, so it appears that both: It appears that new Rails 5 defaults are not so much backwards compatible. Anyhow, thanks all for help. |
@develop-test1 If I got you correctly, you want to store class Post < ActiveRecord::Base
belongs_to :author, optional: true
validate :author_id_correctness
def author_id_correctness
if author_id.present? && Author.find_by(id: author_id).nil?
errors.add(:author_id, "is invalid")
end
end
end |
Awesome! Thank you @mechanicles |
By the way, couldn't this workaround be available as a part of ActiveRecord methods? I.e: |
…rity. By adding this support, model can able to save foreign_key to either `nil` value or to the valid foreign_key value which means foreign_key value must present in the foreign table. class Post < ActiveRecord::Base belongs_to :author, optional: :with_integrity end author = Author.create! post = Post.create!(author_id: author.id) post.author_id = 0 # Invalid id which is not present in database post.save! # Should raise 'ActiveRecord::RecordInvalid' error post.author_id = nil post.save! # No Error Based on this issue's discussion rails#26557. Added this.
I think the It took me a while to find the relevant info across a few Github issues, so perhaps some attention should be called to this in Rails Guides? I have an extremely simple application which is actually using devise_token_auth, which uses In any event, just posting this so there is some awareness that this issue is more widespread than just @develop-test1 |
there is a minor bug 5.1.6
although it is working:
This is due to the automatic inverse_or definition in the reflection library. |
Steps to reproduce
hi, I'm having problem with Rails 5 validation on updating association foreign key on the belongs_to object. I have Post and Author models, where Post belongs to Author. I'm trying to update Post Author via strong params:
params.require(:post).permit(:author_id).
However the author_id is not validated properly, so I can assign author_id that is invalid (Author of that ID doesn't exist). In Rails 4 this would raise 404 not found exception, but Rails 5 just assigns wrong foreign key. Is this desired behaviour?
Expected behavior
404 Not found exception should be raised.
Actual behavior
Invalid foreign_key id is being saved to the DB without validation.
System configuration
Rails version:
5.0.0.rc1
Ruby version:
ruby 2.2.3p173
The text was updated successfully, but these errors were encountered: