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

Creating ApplicationModel #12162

Closed
wants to merge 8 commits into
base: master
from

Conversation

Projects
None yet
9 participants
@wangjohn
Contributor

wangjohn commented Sep 8, 2013

This PR creates the ApplicationModel class. This class will serve as an intermediate between a model and ActiveRecord::Base. Currently, to create a model, one follows the following procedure:

class MyModelName < ActiveRecord::Base
end

This inherits directly from ActiveRecord::Base and means that all configurations on ActiveRecord::Base are global to all of its subclasses (unless the subclass redefines the configuration on its own).

I'm introducing ApplicationModel so that models have an intermediary layer for inheritance like so:

class MyModelName < ApplicationModel
end

What the ApplicationModel class does is allow different sets of configurations to be defined on multiple applications. Each Rails application will have its own ApplicationModel. The ApplicationModel figures out which application it belongs when it is pulled in through the railtie and configs_from is specified.

\cc @spastorino, @josevalim Can you guys take a look? I'm sure there's something I forgot so please let me know.

wangjohn added some commits Sep 4, 2013

Creating a template for ApplicationModel.
The application model will keep all of the Active Record configurations,
instead of sending the configurations directly to ActiveRecord::Base.
This means it will be possible to configure multiple applications if
each application has its own ApplicationModel.

Also, changing some tests to correspond to these changes.
Adding ApplicationModel to the test helper.
The Active Record tests should now include inside of it an
ApplicationModel.
Using ApplicationModel in Active Record tests.
This replaces the current use of ActiveRecord::Base in most tests.
Creating ApplicationModel methods.
These methods will be used by the ApplicationModel to send the correct
configuration.
@robin850

This comment has been minimized.

Show comment
Hide comment
@robin850

robin850 Sep 8, 2013

Member

Awesome pull request, thank you! I've noticed several things:

  • I think that the main README file should be updated since it states that models derived from ActiveRecord::Base, this is still true but not completely. The RDOC_MAIN.rdoc files should be updated as well in each project.
  • All the guides should be updated (mainly all the ActiveRecord ones and "Getting started with Rails"). Also, I think that we should mention the motivation behind the existence of this new class in the "Active Record Basics" guide.

Don't hesitate to ping me if you want some help. 😃 Thank you!

Member

robin850 commented Sep 8, 2013

Awesome pull request, thank you! I've noticed several things:

  • I think that the main README file should be updated since it states that models derived from ActiveRecord::Base, this is still true but not completely. The RDOC_MAIN.rdoc files should be updated as well in each project.
  • All the guides should be updated (mainly all the ActiveRecord ones and "Getting started with Rails"). Also, I think that we should mention the motivation behind the existence of this new class in the "Active Record Basics" guide.

Don't hesitate to ping me if you want some help. 😃 Thank you!

@egilburg

This comment has been minimized.

Show comment
Hide comment
@egilburg

egilburg Sep 8, 2013

Contributor

Thanks! Given the very large scope of this PR could this be a right time to discuss extension vs composition?

I've seen some feedback of people discussing that directly subclassing from ActiveRecord::Base goes counter to Domain-Driven Design, under which class hierarchy should be driven by the problem domain rather than technical implementation. Under this school of thought, the following would be preferable:

class Person
  # Person is the root object under the problem domain.
  # The fact it uses AR::Base as a persistence implementation, shouldn't drive the domain class hierarchy.
  include ActiveRecord::Base # Or ApplicationModel
end

class Client < Person
  # Client is a domain-driven subclass of Person, so it makes sense for it to be an actual subclass
end

The above would also make it more flexible to use include statements either before or after including ActiveRecord::Base (or ApplicationModel), for more granular control over inclusion order and module hierarchy.

This change going to be a disruptive change to matter what, so it's a good time as any to discuss what's the best approach. Thanks again!

Contributor

egilburg commented Sep 8, 2013

Thanks! Given the very large scope of this PR could this be a right time to discuss extension vs composition?

I've seen some feedback of people discussing that directly subclassing from ActiveRecord::Base goes counter to Domain-Driven Design, under which class hierarchy should be driven by the problem domain rather than technical implementation. Under this school of thought, the following would be preferable:

class Person
  # Person is the root object under the problem domain.
  # The fact it uses AR::Base as a persistence implementation, shouldn't drive the domain class hierarchy.
  include ActiveRecord::Base # Or ApplicationModel
end

class Client < Person
  # Client is a domain-driven subclass of Person, so it makes sense for it to be an actual subclass
end

The above would also make it more flexible to use include statements either before or after including ActiveRecord::Base (or ApplicationModel), for more granular control over inclusion order and module hierarchy.

This change going to be a disruptive change to matter what, so it's a good time as any to discuss what's the best approach. Thanks again!

@egilburg

View changes

Show outdated Hide outdated railties/test/generators/namespaced_generators_test.rb
@@ -92,7 +92,7 @@ def test_module_file_is_not_created
def test_adds_namespace_to_model
run_generator
assert_file "app/models/test_app/account.rb", /module TestApp/, / class Account < ActiveRecord::Base/
assert_file "app/models/test_app/account.rb", /module TestApp/, / class Account < ApplicationModel/

This comment has been minimized.

@egilburg

egilburg Sep 8, 2013

Contributor

Should base model classes be generated per namespace? E.g.

module TestApp
  class AppicationModel < ::ApplicationModel
  end
end

module TestApp
  class Account < ApplicationModel
  end
end

Anyone remembers how controller generators work for namespaced controllers?

@egilburg

egilburg Sep 8, 2013

Contributor

Should base model classes be generated per namespace? E.g.

module TestApp
  class AppicationModel < ::ApplicationModel
  end
end

module TestApp
  class Account < ApplicationModel
  end
end

Anyone remembers how controller generators work for namespaced controllers?

This comment has been minimized.

@robin850

robin850 Sep 8, 2013

Member

👍 Good point @egilburg!

@robin850

robin850 Sep 8, 2013

Member

👍 Good point @egilburg!

This comment has been minimized.

@wangjohn

wangjohn Sep 8, 2013

Contributor

Yep, you're right about this. I'll make the change.

@wangjohn

wangjohn Sep 8, 2013

Contributor

Yep, you're right about this. I'll make the change.

@rafaelfranca

This comment has been minimized.

Show comment
Hide comment
@rafaelfranca

rafaelfranca Sep 8, 2013

Member

We already had this discussion in rails 4 and the conclusion was: there are
no real gain other than theoretical thought.

Also include also means inheritance in Ruby, so this change is not worth of
all the the complexity of maintaining the code for support both way
On Sep 8, 2013 3:42 PM, "Eugene Gilburg" notifications@github.com wrote:

Thanks! Given the very large scope of this PR, could this be a right time
to discuss extension vs composition?

I've seen some feedback of people discussing that directly subclassing
from AR::Base goes counter to domain-driven design, under which class
hierarchy should be driven by the problem domain rather than technical
implementation. Under this school of thought, the following would be
preferable:

class Person

Person is the root object under the problem domain.

The fact it uses AR::Base as a persistence implementation, shouldn't drive the domain class hierarchy.

include ActiveRecord::Base # Or ApplicationModelend
class Client < Person

Client is a domain-driven subclass of Person, so it makes sense for it to be an actual subclassend

The above would also make it more flexible to use include statements
either before or after including ActiveRecord::Base (or ApplicationModel),
for more granular control over inclusion order and module hierarchy.


Reply to this email directly or view it on GitHubhttps://github.com/rails/rails/pull/12162#issuecomment-24026590
.

Member

rafaelfranca commented Sep 8, 2013

We already had this discussion in rails 4 and the conclusion was: there are
no real gain other than theoretical thought.

Also include also means inheritance in Ruby, so this change is not worth of
all the the complexity of maintaining the code for support both way
On Sep 8, 2013 3:42 PM, "Eugene Gilburg" notifications@github.com wrote:

Thanks! Given the very large scope of this PR, could this be a right time
to discuss extension vs composition?

I've seen some feedback of people discussing that directly subclassing
from AR::Base goes counter to domain-driven design, under which class
hierarchy should be driven by the problem domain rather than technical
implementation. Under this school of thought, the following would be
preferable:

class Person

Person is the root object under the problem domain.

The fact it uses AR::Base as a persistence implementation, shouldn't drive the domain class hierarchy.

include ActiveRecord::Base # Or ApplicationModelend
class Client < Person

Client is a domain-driven subclass of Person, so it makes sense for it to be an actual subclassend

The above would also make it more flexible to use include statements
either before or after including ActiveRecord::Base (or ApplicationModel),
for more granular control over inclusion order and module hierarchy.


Reply to this email directly or view it on GitHubhttps://github.com/rails/rails/pull/12162#issuecomment-24026590
.

@egilburg

This comment has been minimized.

Show comment
Hide comment
@egilburg

egilburg Sep 8, 2013

Contributor

What impact will there be on Rails Engines? Will there be a separate ApplicationModel per engine?

Contributor

egilburg commented Sep 8, 2013

What impact will there be on Rails Engines? Will there be a separate ApplicationModel per engine?

@fxn

This comment has been minimized.

Show comment
Hide comment
@fxn

fxn Sep 8, 2013

Member

I am 👎 on this one, because ApplicationModel would take over a name whose scope is broader than what it means, because not every model is persisted.

Member

fxn commented Sep 8, 2013

I am 👎 on this one, because ApplicationModel would take over a name whose scope is broader than what it means, because not every model is persisted.

@guilleiguaran

This comment has been minimized.

Show comment
Hide comment
@guilleiguaran

guilleiguaran Sep 8, 2013

Member

@fxn maybe this should be named ApplicationRecord ?

Member

guilleiguaran commented Sep 8, 2013

@fxn maybe this should be named ApplicationRecord ?

@fxn

This comment has been minimized.

Show comment
Hide comment
@fxn

fxn Sep 8, 2013

Member

@guilleiguaran yeah, I believe ApplicationRecord is a better name.

Member

fxn commented Sep 8, 2013

@guilleiguaran yeah, I believe ApplicationRecord is a better name.

@yfeldblum

This comment has been minimized.

Show comment
Hide comment
@yfeldblum

yfeldblum Sep 8, 2013

+1 on ApplicationRecord rather than ApplicationModel.

yfeldblum commented Sep 8, 2013

+1 on ApplicationRecord rather than ApplicationModel.

@thegrubbsian

This comment has been minimized.

Show comment
Hide comment
@thegrubbsian

thegrubbsian Sep 8, 2013

+1 on ApplicationRecord, but I'm also +1 on doing this as an included module.

thegrubbsian commented Sep 8, 2013

+1 on ApplicationRecord, but I'm also +1 on doing this as an included module.

@guilleiguaran

This comment has been minimized.

Show comment
Hide comment
@guilleiguaran

guilleiguaran Sep 8, 2013

Member

-1 about included module. See 9e4c41c for reason

Member

guilleiguaran commented Sep 8, 2013

-1 about included module. See 9e4c41c for reason

@wangjohn

This comment has been minimized.

Show comment
Hide comment
@wangjohn

wangjohn Sep 8, 2013

Contributor

So it seems that most people think it should be called ApplicationRecord, I'll go ahead and make that change. I'll also be starting to slowly change the rdocs and the guides. Thanks everyone for all of the comments/suggestions!

Contributor

wangjohn commented Sep 8, 2013

So it seems that most people think it should be called ApplicationRecord, I'll go ahead and make that change. I'll also be starting to slowly change the rdocs and the guides. Thanks everyone for all of the comments/suggestions!

wangjohn added some commits Sep 7, 2013

Method for finding the correct application model.
This method first checks to see if an application configuration is
defined, then gets the correct ApplicationModel. Reverts to
ActiveRecord::Base if it can't find anything.
Changing comments to use ApplicationModel.
The comments have become outdated since the creation of the
ApplicationModel. Now, the model classes should inherit from
ApplicationModel instead of ActiveRecord::Base.
Renamed ApplicationModel to ApplicationRecord.
This new name is less general and more appropriate since these changes
are limited to Active Record.
@spastorino

This comment has been minimized.

Show comment
Hide comment
@spastorino

spastorino Sep 9, 2013

Member

we agreed with @wangjohn to move his GSoC PRs to this branch https://github.com/rails/rails/tree/rework_initialization

Member

spastorino commented Sep 9, 2013

we agreed with @wangjohn to move his GSoC PRs to this branch https://github.com/rails/rails/tree/rework_initialization

@wangjohn wangjohn closed this Sep 9, 2013

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment