Skip to content
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

[MNOE-688] Generate getter and setter for has_one relationship #560

Open
wants to merge 10 commits into
base: 4.0
Choose a base branch
from

Conversation

x4d3
Copy link
Contributor

@x4d3 x4d3 commented Nov 1, 2017

This PR introduces 2 big changes.

  • The use of a has_one relationship helper
  • Stop loading everything in current_user

has_one relationship helper

This PR introduces an helper to easily create elements with relationships.

o = OrgaRelation.new(role: 'Super Admin')
o.relationships.user = User.new(id: user_id)
o.relationships.organization = User.new(id: organization_id)
o.save!

is replaced by

OrgaRelation.create!(user: user, organization: organization, role: 'Super Admin')

make current_user call smaller

In the current version, current_user is preloaded with a lot of dependencies, which are not always used. This can introduce problems of performances, caching and pagination. The objective of this PR is too stop relying on the autoload of theses dependencies and let the controllers manage the loading of what they need.

class_methods do
def has_one(attr_name, options = {})
class_eval <<-CODE
def #{attr_name}_id=(id)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Coud you add something like:

ActiveSupport::Deprecation.warn('Use relationships instead')
# => "DEPRECATION WARNING: Use relationships instead (called from your_code.rb:1)"

This will allow us to spot and progressively replace all the calls

@x4d3 x4d3 force-pushed the feature/add-relationship-helper branch from fef78ca to 6a09fe5 Compare November 8, 2017 16:54
@ouranos ouranos added this to the v4.0 milestone Nov 9, 2017
@x4d3 x4d3 force-pushed the feature/add-relationship-helper branch from 455932a to 58cb46c Compare November 9, 2017 17:43
@x4d3 x4d3 changed the title WIP [MNOE-688] Generate relation_id getter and setter for has_one relationship WIP [MNOE-688] Generate getter and setter for has_one relationship Nov 9, 2017
@x4d3 x4d3 force-pushed the feature/add-relationship-helper branch from 58cb46c to 62459b1 Compare November 9, 2017 18:04
@x4d3 x4d3 force-pushed the feature/add-relationship-helper branch 2 times, most recently from a702359 to 9715076 Compare November 14, 2017 16:07
@x4d3 x4d3 requested a review from manu-d November 14, 2017 16:14
def dashboard_template
@dashboard_template ||= dashboard_templates.find(params[:id].to_i).first
def load_organizations
@organizations = MnoEnterprise::Organization.where('user.ids': current_user.id)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@organizations = MnoEnterprise::Organization.where('users.id': current_user.id)

def parent_organization
@parent_organization ||= current_user.organizations.to_a.find { |o| o.id.to_s == params[:organization_id].to_s }
@parent_organization ||= MnoEnterprise::Organization.where(user_id: current_user.id, id: params[:organization_id]).first
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@parent_organization ||= MnoEnterprise::Organization.where('users.id': current_user.id, id: params[:organization_id]).first

end

def render_forbidden_request(attempted_action)
render json: { errors: {message: "Error while trying to #{attempted_action}: you do not have permission", code: 403} }, status: :forbidden
render json: { errors: { message: "Error while trying to #{attempted_action}: you do not have permission", code: 403 } }, status: :forbidden
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can't you put this 3 methods in application_controller.rb, so that you dont' have to repeat them as well in the non_admin base controller?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

@@ -18,5 +17,6 @@ module MnoEnterprise::Concerns::Controllers::Jpi::V1::Impac::DashboardTemplatesC
# GET /mnoe/jpi/v1/impac/dashboard_templates
def index
@templates = MnoEnterprise::Dashboard.published_templates.includes(*DASHBOARD_DEPENDENCIES)
@organizations = MnoEnterprise::Organization.where('user.ids': current_user.id)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@organizations = MnoEnterprise::Organization.where('users.id': current_user.id)

@@ -18,11 +18,13 @@ module MnoEnterprise::Concerns::Controllers::Jpi::V1::Impac::DashboardsControlle
# GET /mnoe/jpi/v1/impac/dashboards
def index
dashboards
@organizations = MnoEnterprise::Organization.where('user.ids': current_user.id)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@organizations = MnoEnterprise::Organization.where('users.id': current_user.id)

@@ -46,7 +49,7 @@ def update
# TODO: enable authorization
# authorize! :manage_dashboard, dashboard
dashboard.update_attributes!(dashboard_update_params)

@organizations = MnoEnterprise::Organization.where('user.ids': current_user.id)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@organizations = MnoEnterprise::Organization.where('users.id': current_user.id)

@@ -73,6 +76,7 @@ def copy
# Owner is the current user by default, can be overriden to something else (eg: current organization)
@dashboard = template.copy!(current_user, dashboard_params[:name], dashboard_params[:organization_ids])
@dashboard = @dashboard.load_required(DASHBOARD_DEPENDENCIES)
@organizations = MnoEnterprise::Organization.where('user.ids': current_user.id)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@organizations = MnoEnterprise::Organization.where('users.id': current_user.id)

@@ -17,7 +17,7 @@ module MnoEnterprise::Concerns::Controllers::Jpi::V1::Impac::WidgetsController
# -> GET /api/mnoe/v1/organizations/:id/widgets
def index
render_not_found('organization') unless parent_organization
@widgets = MnoEnterprise::Widget.find(organization_id: parent_organization.id)
@widgets = MnoEnterprise::Widget.find(organization_id: parent_organization_id)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

parent_organization_id can be an uid as well

@widgets = MnoEnterprise::Widget.where('organization.id': parent_organization.id)


subscription = MnoEnterprise::Subscription.where(organization_id: parent_organization.id, id: params[:id]).first
subscription = MnoEnterprise::Subscription.where(organization_id: parent_organization_id, id: params[:id]).first
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

subscription = MnoEnterprise::Subscription.where('organization.id': parent_organization_id, id: params[:id]).first


subscription = MnoEnterprise::Subscription.where(organization_id: parent_organization.id, id: params[:id]).first
subscription = MnoEnterprise::Subscription.where(organization_id: parent_organization_id, id: params[:id]).first
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

subscription = MnoEnterprise::Subscription.where('organization.id': parent_organization_id, id: params[:id]).first

@x4d3 x4d3 changed the title WIP [MNOE-688] Generate getter and setter for has_one relationship [MNOE-688] Generate getter and setter for has_one relationship Nov 15, 2017
Copy link
Contributor

@ouranos ouranos left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See comments.

Have you done some local performance testing?
I have the feeling that, in some cases, it might not be faster as you're trading a smaller response for more API requests.

@@ -1,6 +1,8 @@
module MnoEnterprise
class Jpi::V1::Admin::Impac::DashboardTemplatesController < Jpi::V1::Admin::BaseResourceController

before_action :load_organizations, except: [:destroy]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where's @organizations used? Only in the view?
With the before_action you're loading organizations all the time, even if the find_one! or save! is going to fail

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

True. I'll update it.

end

def orga_relation
MnoEnterprise::OrgaRelation.where('user.id' => current_user.id, 'organization.id': params[:organization_id]).first
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you need the full orga_relation here? Otherwise just add select(:id)?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point.

class_eval <<-CODE
def #{attr_name}_id=(id)
# Uncomment when doing refactoring
# ActiveSupport::Deprecation.warn(self.class.name + ".#{attr_name}_id= Use relationships instead")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should not be commented?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it should be not commented during development, but not for prod. I will add a check.

@@ -15,14 +15,14 @@ def column_names

# @see OrmAdapter::Base#get!
def get!(id)
res = klass.includes(*klass::INCLUDED_DEPENDENCIES).find(wrap_key(id)).first
res = klass.find(wrap_key(id)).first
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you removing the INCLUDED_DEPENDENCIES feature? Was it widely used or just for the current_user?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it was mainly used for the current_user, but also for other controllers. (for example when current_user.organizations was called)

@@ -94,11 +94,6 @@ def add_user!(user, role = 'Member')
MnoEnterprise::OrgaRelation.create!(organization_id: self.id, user_id: user.id, role: role)
end

def provision_app_instance!(app_nid)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

see #584
This is going to introduce regressions

@x4d3
Copy link
Contributor Author

x4d3 commented Nov 22, 2017

I will check the performance. The problem is that includes does not really work in v2, as it does not paginates. On top of that the MnoHub calls can be very long to build up the user with all the dependencies. It's definitely more interesting to make more smaller calls, easy to cache and reproduce than complicated calls with multiple includes.

@x4d3 x4d3 force-pushed the feature/add-relationship-helper branch 2 times, most recently from 7194ed3 to 0c97737 Compare November 27, 2017 17:30
Copy link
Contributor

@ouranos ouranos left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

core/lib/mno_enterprise/concerns/controllers/auth/omniauth_callbacks_controller.rb still calls provision_app_instance!

(Might need an extra spec if this hasn't been picked up)

@@ -59,4 +58,5 @@ def destroy
head :bad_request
end
end

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Empty line 👮‍♂️

@x4d3 x4d3 force-pushed the feature/add-relationship-helper branch from 7cad9eb to 5c456f3 Compare December 1, 2017 09:20
alachaum
alachaum previously approved these changes Dec 4, 2017
Copy link

@alachaum alachaum left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 looks good to me

x4d3 added 10 commits December 4, 2017 14:39
…nship

- Introduce HasOneExtension, generating getter and setter for has_one relations, making them saved in relationships, and allowing their retrieving from a relations cache
- Remove useless timestamp method
- Rplace is_integer by is_id that is more semantic
- Try to not rely on parent_organization
Each controller must be in charge of managing its own payload.
- fix issue with provisioning + update spec
- Add log warning in has_one in test and development
@x4d3 x4d3 force-pushed the feature/add-relationship-helper branch from 5c456f3 to 9a5b025 Compare December 4, 2017 14:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants