aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib/active_record/model_schema.rb
Commit message (Collapse)AuthorAgeFilesLines
* Better error message for calling columns_hashGuilherme Mansur2019-06-191-0/+3
| | | | | | | | | | | | When a record does not have a table name, as in the case for a record with `self.abstract_class = true` and no `self.table_name` set the error message raises a cryptic: "ActiveRecord::StatementInvalid: Could not find table ''" this patch now raises a new `TableNotSpecified Error` Fixes: #36274 Co-Authored-By: Eugene Kenny <elkenny@gmail.com>
* Enable `Layout/EmptyLinesAroundAccessModifier` copRyuta Kamizono2019-06-131-2/+0
| | | | | | | | | | | We sometimes say "✂️ newline after `private`" in a code review (e.g. https://github.com/rails/rails/pull/18546#discussion_r23188776, https://github.com/rails/rails/pull/34832#discussion_r244847195). Now `Layout/EmptyLinesAroundAccessModifier` cop have new enforced style `EnforcedStyle: only_before` (https://github.com/rubocop-hq/rubocop/pull/7059). That cop and enforced style will reduce the our code review cost.
* Make implicit order column configurableTekin Suleyman2018-11-261-0/+16
| | | | | | | | | | | | | | When calling ordered finder methods such as +first+ or +last+ without an explicit order clause, ActiveRecord sorts records by primary key. This can result in unpredictable and surprising behaviour when the primary key is not an auto-incrementing integer, for example when it's a UUID. This change makes it possible to override the column used for implicit ordering such that +first+ and +last+ will return more predictable results. For Example: class Project < ActiveRecord::Base self.implicit_order_column = "created_at" end
* ActiveRecord#respond_to? No longer allocates stringsschneems2018-10-151-0/+6
| | | | | | | | | | | | | | | | | This is an alternative to https://github.com/rails/rails/pull/34195 The active record `respond_to?` method needs to do two things if `super` does not say that the method exists. It has to see if the "name" being passed in represents a column in the table. If it does then it needs to pass it to `has_attribute?` to see if the key exists in the current object. The reason why this is slow is that `has_attribute?` needs a string and most (almost all) objects passed in are symbols. The only time we need to allocate a string in this method is if the column does exist in the database, and since these are a limited number of strings (since column names are a finite set) then we can pre-generate all of them and use the same string. We generate a list hash of column names and convert them to symbols, and store the value as the string name. This allows us to both check if the "name" exists as a column, but also provides us with a string object we can use for the `has_attribute?` call. I then ran the test suite and found there was only one case where we're intentionally passing in a string and changed it to a symbol. (However there are tests where we are using a string key, but they don't ship with rails). As re-written this method should never allocate unless the user passes in a string key, which is fairly uncommon with `respond_to?`. This also eliminates the need to special case every common item that might come through the method via the `case` that was originally added in https://github.com/rails/rails/commit/f80aa5994603e684e3fecd3f53bfbf242c73a107 (by me) and then with an attempt to extend in https://github.com/rails/rails/pull/34195. As a bonus this reduces 6,300 comparisons (in the CodeTriage app homepage) to 450 as we also no longer need to loop through the column array to check for an `include?`.
* Fix call sitesGannon McGibbon2018-10-021-5/+5
|
* Make a deep copy of the _default_attributes in column_defaultsRafael Mendonça França2018-09-201-1/+1
| | | | | | | | | | When column_defaults is called it calls `value` on each instance of Attribute inside the _default_attributes set. Since value is memoized in the Attribute instance and that Attribute instance is shared across all instances of a model the next call to the default value will be memozied not running the proc defined by the user. Fixes #33031.
* Add AR::Base.base_class? predicateBogdan Gusiev2018-04-021-4/+3
|
* Invoke `load_schema` in `_default_attributes`Ryuta Kamizono2018-02-061-0/+1
| | | | | | | | | | | | | Currently `_default_attributes` doesn't work unless `load_schema` is called before. The `MissingAttributeError` is caused by `reload_schema_from_cache` is invoked by `serialize`. I added `load_schema` in `_default_attributes` to `_default_attributes` works without any dependency like `attribute_types` etc. Closes #31905.
* Allow type_for_attribute(:symbol)Beni Cherniavsky-Paskin2018-01-011-1/+2
| | | | Closes #31611.
* Undefine attribute methods on all descendants when resetting column infoChris Salzberg2017-12-171-1/+1
| | | | | | | If we don't do this, then we end up with an inconsistent situation where a parent class may e.g. reset column information, but child classes will contine to see attribute methods as already generated, and thus not pick up this new column (falling through to method_missing).
* Convert protected_environments to an array of stringsbogdanvlviv2017-12-121-14/+16
| | | | | | | These changes prevent ignoring environments name of which is a `Symbol` ``` config.active_record.protected_environments = ['staging', :production] ```
* Change how `AttributeSet::Builder` receives its defaultsSean Griffin2017-11-271-4/+4
| | | | | | | | | | | | | | | | | | | | | There are two concerns which are both being combined into one here, but both have the same goal. There are certain attributes which we want to always consider initialized. Previously, they were handled separately. The primary key (which is assumed to be backed by a database column) needs to be initialized, because there is a ton of code in Active Record that assumes `foo.id` will never raise. Additionally, we want attributes which aren't backed by a database column to always be initialized, since we would never receive a database value for them. Ultimately these two concerns can be combined into one. The old implementation hid a lot of inherent complexity, and is hard to optimize from the outside. We can simplify things significantly by just passing in a hash. This has slightly different semantics from the old behavior, in that `Foo.select(:bar).first.id` will return the default value for the primary key, rather than `nil` unconditionally -- however, the default value is always `nil` in practice.
* Move Attribute and AttributeSet to ActiveModelLisa Ugray2017-11-091-3/+3
| | | | | Use these to back the attributes API. Stop automatically including ActiveModel::Dirty in ActiveModel::Attributes, and make it optional.
* Convert ignored_columns to a list of stringAltech2017-10-201-15/+17
|
* Use frozen-string-literal in ActiveRecordKir Shatrov2017-07-191-0/+2
|
* Remove useless `arel_engine`Ryuta Kamizono2017-07-171-1/+0
| | | | | | | | | | | `arel_engine` is only used in `raise_record_not_found_exception!` to use `engine.connection` (and `connection.visitor`) in `arel.where_sql`. https://github.com/rails/arel/blob/v8.0.0/lib/arel/select_manager.rb#L183 But `klass.connection` will work as expected even if not using `arel_engine` (described by `test_connection`). So `arel_engine` is no longer needed.
* Revert "Merge pull request #29540 from kirs/rubocop-frozen-string"Matthew Draper2017-07-021-1/+0
| | | | | This reverts commit 3420a14590c0e6915d8b6c242887f74adb4120f9, reversing changes made to afb66a5a598ce4ac74ad84b125a5abf046dcf5aa.
* Enforce frozen string in RubocopKir Shatrov2017-07-011-0/+1
|
* Don't mark the schema loaded until it's really finishedMatthew Draper2017-06-051-3/+5
| | | | | load_schema! is overridden by attribute modules, so we need to wait until it has returned.
* Add option for class_attribute default (#29270)David Heinemeier Hansson2017-05-291-20/+7
| | | | | | | | | | | | * Allow a default value to be declared for class_attribute * Convert to using class_attribute default rather than explicit setter * Removed instance_accessor option by mistake * False is a valid default value * Documentation
* Merge pull request #29215 from voxmedia/ar_optimizationsMatthew Draper2017-05-261-1/+2
|\ | | | | ActiveRecord initialization optimizations
| * Performance optimization for ActiveRecord#column_defaultsMichael Lovitt2017-05-241-1/+2
| | | | | | | | | | | | | | | | | | | | Memoize the #column_defaults class property, as ActiveRecord does for other properties in this module. This change addresses slowness in ActiveRecord initialization introduced starting in Rails 5.0. This method's performance has not changed with Rails 5, but it is now called much more frequently than before: every time an STI model is instantiated.
* | Add a Monitor to ModelSchema#load_schemaMatthew Draper2017-05-251-3/+22
|/ | | | [Vikrant Chaudhary, David Abdemoulaie, Matthew Draper]
* Make `table_name=` reset current statement cachenamusyaka2017-02-121-0/+1
| | | | | | So queries are not run against the previous table name. Closes #27953
* Add missing `+` around a some literals.bogdanvlviv2016-10-271-1/+1
| | | | | | Mainly around `nil` [ci skip]
* Copy-edits on #26880Rafael Mendonça França2016-10-241-32/+52
| | | | | | | | | | * Put a blank line after :call-seq: otherwise it will think the whole test is the call seq. * Improve some text. * Use some rdoc formatting. * Restores the documentation of table_name_prefix. [ci skip]
* Fix model schema doc stringsMia Zbikowski2016-10-241-44/+103
|
* Fix broken comments indentation caused by rubocop auto-correct [ci skip]Ryuta Kamizono2016-09-141-2/+2
| | | | | | All indentation was normalized by rubocop auto-correct at 80e66cc4d90bf8c15d1a5f6e3152e90147f00772. But comments was still kept absolute position. This commit aligns comments with method definitions for consistency.
* Remove deprecated handling of PG PointsSean Griffin2016-08-311-23/+0
| | | | | | | | | | There are some minor changes to the point type as I had forgotten that this will affect the behavior of `t.point` in migrations and the schema dumper so we need to handle those as well. I'll say this again so I can convince myself to come up with a better structure... TYPES SHOULD NOT CARE ABOUT SCHEMA DUMPING AND WE NEED TO BETTER SEPARATE THESE.
* Add `Type.default_value` and use it everywhere for internalRyuta Kamizono2016-08-261-1/+1
| | | | For reduce instantiating `Type::Value`.
* Add three new rubocop rulesRafael Mendonça França2016-08-161-2/+2
| | | | | | | | Style/SpaceBeforeBlockBraces Style/SpaceInsideBlockBraces Style/SpaceInsideHashLiteralBraces Fix all violations in the repository.
* code gardening: removes redundant selfsXavier Noria2016-08-081-1/+1
| | | | | | | | | A few have been left for aesthetic reasons, but have made a pass and removed most of them. Note that if the method `foo` returns an array, `foo << 1` is a regular push, nothing to do with assignments, so no self required.
* normalizes indentation and whitespace across the projectXavier Noria2016-08-061-62/+62
|
* applies new string literal convention in activerecord/libXavier Noria2016-08-061-4/+4
| | | | | The current code base is not uniform. After some discussion, we have chosen to go with double quotes by default.
* Correct the behavior of virtual attributes on models loaded from the dbSean Griffin2016-07-251-1/+5
| | | | | | | | | | | | | | | | | | | | | | | | | | | Previously we had primarily tested the behavior of these attributes by calling `.new`, allowing this to slip through the cracks. There were a few ways in which they were behaving incorrectly. The biggest issue was that attempting to read the attribute would through a `MissingAttribute` error. We've corrected this by returning the default value when the attribute isn't backed by a database column. This is super special cased, but I don't see a way to avoid this conditional. I had considered handling this higher up in `define_default_attribute`, but we don't have the relevant information there as users can provide new defaults for database columns as well. Once I corrected this, I had noticed that the attributes were always being marked as changed. This is because the behavior of `define_default_attribute` was treating them as assigned from `Attribute::Null`. Finally, with our new implementation, `LazyAttributeHash` could no longer be marshalled, as it holds onto a proc. This has been corrected as well. I've not handled YAML in that class, as we do additional work higher up to avoid YAML dumping it at all. Fixes #25787 Close #25841
* systematic revision of =~ usage in ARXavier Noria2016-07-231-1/+6
| | | | | Where appropriatei, prefer the more concise Regexp#match?, String#include?, String#start_with?, or String#end_with?
* Always prefer class types to query types when casting `group`Sean Griffin2016-07-111-2/+6
| | | | | | | | | | | | | When `group` is used in combination with any calculation method, the resulting hash uses the grouping expression as the key. Currently we're incorrectly always favoring the type reported by the query, instead of the type known by the class. This causes differing behavior depending on whether the adaptor actually gives proper types with the query or not. After this change, the behavior will be the same on all adaptors -- we see if we know the type from the class, fall back to the type from the query, and finally fall back to the identity type. Fixes #25595
* Make Active Record emit significantly smaller YAMLSean Griffin2016-05-311-0/+5
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This reduces the size of a YAML encoded Active Record object by ~80% depending on the number of columns. There were a number of wasteful things that occurred when we encoded the objects before that have resulted in numerous wins - We were emitting the result of `attributes_before_type_cast` as a hack to work around some laziness issues - The name of an attribute was emitted multiple times, since the attribute objects were in a hash keyed by the name. We now store them in an array instead, and reconstruct the hash using the name - The types were included for every attribute. This would use backrefs if multiple objects were encoded, but really we don't need to include it at all unless it differs from the type at the class level. (The only time that will occur is if the field is the result of a custom select clause) - `original_attribute:` was included over and over and over again since the ivar is almost always `nil`. We've added a custom implementation of `encode_with` on the attribute objects to ensure we don't write the key when the field is `nil`. This isn't without a cost though. Since we're no longer including the types, an object can find itself in an invalid state if the type changes on the class after serialization. This is the same as 4.1 and earlier, but I think it's worth noting. I was worried that I'd introduce some new state bugs as a result of doing this, so I've added an additional test that asserts mutation not being lost as the result of YAML round tripping. Fixes #25145
* s/statment/statement/Vipul A M2016-04-241-1/+1
|
* Revert "Deprecate table names containing dots"Sean Griffin2016-03-311-7/+0
| | | | | | This reverts commit 7b82e1c77b48cb351da4e0ed6ea0bac806d4925c. This would have removed the ability to reference a schema when using PG
* Deprecate table names containing dotsSean Griffin2016-03-311-0/+7
| | | | | | | | Dots have special meaning in most backends (e.g. everything except SQLite3), as well as most methods that work with table or column names. This isn't something that we ever explicitly supported, but there's at least one case of somebody using this (see #24367), so we'll go through a deprecation cycle as normal.
* Move sequence value methods to Model levelArthur Neves2016-03-241-0/+12
| | | | | | | | | | | | | | | `prefetch_primary_key?` and `next_sequence_value` methods live in the connection level at the moment, that make sense when you are generating the sequence from the database, in the same connection. Which is the use case today at the Oracle and Postgres adapters. However if you have an service that generates IDs, that has nothing to do with the database connection, and should not be fetched from there. Another use case, is if you want to use another connection to fetch IDs, that would not be possible with the current implementation, however when we move those methods to the model level, you can use a new connection there. Also this makes easier for gems to add behavior on those methods.
* Shorten ActiveRecord::InternalMetadata.table_name to ar_internal_metadataYasuo Honda2016-02-011-2/+2
| | | | to support Oracle database which only supports 30 byte identifier length
* Add `ModelSchema::type_for_attribute` to the public APISean Griffin2016-01-191-1/+12
| | | | | | | | | | | We want this method to be the single canonical source of information about type metadata related to a model. This is the method I've been continuously recommending people use if they need this sort of access, as I have no plans to remove or change it at any point in the future. We can do ourselves a favor and get people to use this instead of relying on some other part of the internals that they shouldn't be by making this method public.
* Merge pull request #22967 from schneems/schneems/generic-metadataSean Griffin2016-01-081-0/+13
|\ | | | | Prevent destructive action on production database
| * Prevent destructive action on production databaseschneems2016-01-071-0/+13
| | | | | | | | | | | | | | This PR introduces a key/value type store to Active Record that can be used for storing internal values. It is an alternative implementation to #21237 cc @sgrif @matthewd. It is possible to run your tests against your production database by accident right now. While infrequently, but as an anecdotal data point, Heroku receives a non-trivial number of requests for a database restore due to this happening. In these cases the loss can be large. To prevent against running tests against production we can store the "environment" version that was used when migrating the database in a new internal table. Before executing tests we can see if the database is a listed in `protected_environments` and abort. There is a manual escape valve to force this check from happening with environment variable `DISABLE_DATABASE_ENVIRONMENT_CHECK=1`.
* | Call the new point behavior `:point`, not `:rails_5_1_point`Sean Griffin2015-12-171-1/+1
|/ | | | | Since the attributes API is new in Rails 5, we don't actually need to keep the behavior of `attribute :point`, as it's not a breaking change.
* Use a real migration version number in docsMatthew Draper2015-12-151-1/+1
| | | | | Even though this means more things to change when we bump after a release, it's more important that our examples are directly copyable.
* Use a deliberately-invalid migration version in all doc examplesMatthew Draper2015-12-151-1/+1
| | | | | | | | | | If we use a real version, at best that'll be an onerous update required for each release; at worst, it will encourage users to write new migrations against an older version than they're using. The other option would be to leave these bare, without any version specifier. But as that's just a variant spelling of "4.2", it would seem to raise the same concerns as above.
* Ensure `#reset_column_information` clears child classes as wellSean Griffin2015-11-071-0/+3
| | | | | | | | | | | | | | I've added a redundant test for this under the attributes API as well, as that also causes this bug to manifest through public API (and demonstrates that calling `reset_column_information` on the child classes would be insufficient) Since children of a class should always share a table with their parent, just reloading the schema from the cache should be sufficient here. `reload_schema_from_cache` should probably become public and `# :nodoc:`, but I'd rather avoid the git churn here. Fixes #22057