Giter Site home page Giter Site logo

Comments (16)

smadeja avatar smadeja commented on May 13, 2024 7

Personally, I think that the validate prefix approach is better because such a name will always explain exactly what the method does. It's more important that the method's name is precise than that the validation line reads well.

from rails-style-guide.

yjukaku avatar yjukaku commented on May 13, 2024 7

To add to @pirj 's excellent summary, I think the method name should have a required prefix, whether it's must_ or validate_. IMO, it's helpful to easily recognize that the method is a custom validation by the prefix rather than scanning the entire method name to see if it includes must/validate.

eg.

# Good
validate :validate_birthday_in_past
validate :validate_owner_has_no_other_items

# Also good

validate :must_have_owner_with_no_other_items
validate :must_have_birthday_in_past

# Bad
validate :birthday_in_past_validation
validate :owner_has_no_other_items_validation

validate :birthday_must_be_in_past
validate :owner_must_not_have_other_items

Then I think the ideal criteria would be

  1. The name should indicate that the method is a "custom validation", not a predicate method.
  2. The name causes the validate :method_name line to read like a natural statement
  3. The name should reflect what it does on its own
  4. The method should be instantly recognizable as a validation method.

from rails-style-guide.

smadeja avatar smadeja commented on May 13, 2024 5

Just to expand on my post, methods are what makes up the API that's going to be reused. If I'm scanning through the method list and see something like name_must_be_snake_case, I don't immediately know what that method does. It could be used for validation but it could also return a boolean that indicates if name must be snake_case or not. If that method were called validate_name_is_snake_case, I'd know at once that it's not something I'd want to reuse for anything other than validation.

from rails-style-guide.

jgigault avatar jgigault commented on May 13, 2024 4

This discussion is very interesting and instructive :-)
I would like to share with you the linter we implemented in our project for that purpose ("validate_" prefix).

# frozen_string_literal: true

module RuboCop
  module Cop
    # Ensure custom validators to have prefix "validate_"
    class UsePrefixForCustomValidator < RuboCop::Cop::Cop
      MSG = 'Add a prefix "validate_" to custom validator names'

      CUSTOM_VALIDATOR_METHOD = :validate

      def on_send(node)
        method = method_name(node)

        return unless custom_validator_method?(method)

        first_argument_node = first_argument(node)

        add_offense(first_argument_node, location: :expression) if missing_prefix?(first_argument_node.value)
      end

      private

      def custom_validator_method?(method)
        method == CUSTOM_VALIDATOR_METHOD
      end

      def method_name(node)
        node.children[1]
      end

      def first_argument(node)
        node.arguments[0]
      end

      def missing_prefix?(custom_validator_name)
        !custom_validator_name.to_s.start_with?('validate_')
      end
    end
  end
end

from rails-style-guide.

RKushnir avatar RKushnir commented on May 13, 2024 2

I find that repeating the word "validate" doesn't read well. So I prefer naming them with a phrase containing "must":

validate :must_have_enough_capacity
validate :must_be_enabled
validate :start_date_must_precede_end_date

This helps avoid the above mentioned confusion with methods that return true/false, and also reads as a specification.

from rails-style-guide.

eliotsykes avatar eliotsykes commented on May 13, 2024 2

Just like the validate_ prefix naming practice, a good number of open source projects adopt the must naming practice (see end of comment for examples).

What can we distill from these two practices, without being prescriptive about the verb used? Here's one possible guideline:

Choose names for custom validation methods that capture the method is responsible for validation only. Avoid names which imply the method returns a boolean and/or the method has no side effects.

# bad
class Person < ApplicationRecord
  validate :birthday_in_past

  # method name misleadingly suggests it returns a boolean and
  # has no side effects.
  def birthday_in_past
    errors.add(:birthday, "must be in past") unless birthday.past?
  end
end

# good
class Person < ApplicationRecord
  # it is common practice to use a verb like "validate" or "must"
  # in custom validation method names
  validate :validate_birthday_in_past
  # or using "must": validate :birthday_must_be_in_past

  def validate_birthday_in_past
    errors.add(:birthday, "must be in past") unless birthday.past?
  end
end

Feedback encouraged!


Examples of must naming practice from select open-source projects

$ ag --ruby 'validate .+must'
apps/accelerated_claims/app/models/deposit.rb
15:  validate :money_or_property_must_be_selected_if_received
17:  validate :information_given_date_must_not_be_invalid

apps/accelerated_claims/app/models/notice.rb
20:  validate :expiry_date_must_be_after_served_date

apps/alaveteli/app/models/info_request_event.rb
94:  validate :must_be_valid_state

apps/alaveteli/app/models/info_request.rb
72:  validate :must_be_internal_or_external
151:  validate :must_be_valid_state

apps/askthem/app/models/question.rb
65:  validate :state_must_be_included_in_the_list_of_states
66:  validate :subject_must_be_included_in_the_list_of_subjects
67:  validate :question_and_person_must_belong_to_the_same_jurisdiction
68:  validate :person_and_bill_must_belong_to_the_same_jurisdiction

apps/canvas-lms/app/models/access_token.rb
33:  validate :must_only_include_valid_scopes, unless: :deleted?

apps/canvas-lms/app/models/discussion_entry.rb
51:  validate :must_be_reply_to_same_discussion, on: :create

apps/canvas-lms/app/models/discussion_topic.rb
82:  validate :section_specific_topics_must_have_sections

apps/canvas-lms/app/models/pseudonym.rb
37:  validate :must_be_root_account

apps/canvas-lms/app/models/role_override.rb
28:  validate :must_apply_to_something

apps/catarse/app/models/concerns/contribution/custom_validators.rb
7:    validate :reward_must_be_from_project
8:    validate :value_must_be_at_least_rewards_value

apps/diaspora/app/models/reshare.rb
9:  validate :root_must_be_public

apps/diaspora/app/models/user_preference.rb
6:  validate :must_be_valid_email_type

apps/discourse/app/models/embeddable_host.rb
4:  validate :host_must_be_valid

apps/foodsoft/app/models/delivery.rb
10:  validate :stock_articles_must_be_unique

apps/gitlabhq/app/models/project_label.rb
9:  validate :title_must_not_exist_at_group_level

apps/growstuff/app/models/crop.rb
42:  validate :must_be_rejected_if_rejected_reasons_present
43:  validate :must_have_meaningful_reason_for_rejection

apps/growstuff/app/models/harvest.rb
67:  validate :crop_must_match_planting
68:  validate :owner_must_match_planting
69:  validate :harvest_must_be_after_planting

apps/growstuff/app/models/planting.rb
48:  validate :finished_must_be_after_planted
49:  validate :owner_must_match_garden_owner

apps/lale-help/app/models/sponsorship.rb
7:  validate :ends_on_must_be_before_starts_on

apps/locomotivecms-engine/app/models/locomotive/concerns/content_type/entry_template.rb
13:          validate :entry_template_must_be_valid

apps/locomotivecms-engine/app/models/locomotive/concerns/site/access_points.rb
26:          validate                  :domains_must_be_valid_and_unique
27:          validate                  :domains_must_not_be_reserved
28:          validate                  :asset_host_must_be_valid

apps/manageiq/app/models/miq_provision_configured_system_request.rb
6:  validate               :must_have_user

apps/manageiq/app/models/miq_provision_request.rb
17:  validate               :must_have_user

apps/manageiq/app/models/miq_retire_request.rb
4:  validate :must_have_user

apps/manageiq/app/models/service_reconfigure_request.rb
7:  validate :must_have_user

apps/manageiq/app/models/service_template_provision_request.rb
7:  validate               :must_have_user

apps/manageiq/app/models/vm_migrate_request.rb
7:  validate               :must_have_user

apps/manageiq/app/models/vm_cloud_reconfigure_request.rb
8:  validate  :must_have_user

apps/manageiq/app/models/vm_reconfigure_request.rb
7:  validate               :must_have_user

apps/markus/app/models/student_membership.rb
21:  validate :must_be_valid_student

apps/markus/app/models/ta_membership.rb
2:  validate :must_be_a_ta

apps/mastodon/app/models/custom_filter.rb
30:  validate :context_must_be_valid
31:  validate :irreversible_must_be_within_context

apps/metrics/app/models/metric.rb
24:  validate :pattern_must_be_valid
25:  validate :pattern_must_not_contain_reserved_names, if: :valid_pattern?
26:  validate :feedback_must_not_contain_unknown_names, if: :valid_pattern?

apps/radiant/app/models/radiant/config.rb
321:    validate :definition_must_be_valid

apps/ror_ecommerce/app/models/inventory.rb
20:  validate :must_have_stock

apps/shoppe/app/models/shoppe/stock_level_adjustment.rb
12:    validate { errors.add(:adjustment, I18n.t('shoppe.activerecord.attributes.stock_level_adjustment.must_be_greater_or_equal_zero')) if adjustment == 0 }

apps/signonotron2/app/models/bulk_grant_permission_set.rb
8:  validate :must_have_at_least_one_supported_permission

apps/solidus/core/app/models/spree/return_authorization.rb
22:    validate :must_have_shipped_units, on: :create

apps/spree/core/app/models/spree/customer_return.rb
14:    validate :must_have_return_authorization, on: :create

apps/spree/core/app/models/spree/product.rb
104:    validate :discontinue_on_must_be_later_than_available_on, if: -> { available_on && discontinue_on }

apps/spree/core/app/models/spree/promotion.rb
27:    validate :expires_at_must_be_later_than_starts_at, if: -> { starts_at && expires_at }

apps/spree/core/app/models/spree/return_authorization.rb
22:    validate :must_have_shipped_units, on: :create

apps/squash-web/app/models/comment.rb
65:  validate :user_must_have_permission_to_comment

apps/squash-web/app/models/email.rb
69:  validate :user_must_be_member_of_project

apps/squash-web/app/models/bug.rb
182:  validate :open_bugs_cannot_be_deployed, :assigned_user_must_be_project_member,

apps/test_track/app/models/app.rb
8:  validate :auth_secret_must_be_sufficiently_strong

apps/test_track/app/models/assignment.rb
14:  validate :variant_must_exist

apps/test_track/app/models/bulk_assignment_creation.rb
13:  validate :most_identifiers_must_exist

apps/test_track/app/models/identifier_type.rb
6:  validate :name_must_be_snake_case

apps/test_track/app/models/identifier_claim.rb
9:  validate :identifier_type_must_exist

apps/test_track/app/models/split.rb
12:  validate :name_must_be_snake_case
13:  validate :name_must_not_include_new
14:  validate :name_must_not_end_with_test
15:  validate :variants_must_be_snake_case
16:  validate :registry_weights_must_sum_to_100
17:  validate :registry_weights_must_be_integers

apps/test_track/app/models/split_creation.rb
7:  validate :split_must_be_valid

apps/test_track/app/models/variant_detail.rb
6:  validate :variant_must_exist

apps/tomatoes/app/models/tomato.rb
14:  validate :must_not_overlap, on: :create

apps/uberzeit/app/models/concerns/customer_assignable.rb
9:    validate :customer_must_exist

apps/uberzeit/app/models/absence.rb
40:  validate :must_not_overlap_with_other_absences

apps/uberzeit/app/models/time_entry.rb
34:  validate :must_be_only_timer_on_date, if: :timer?

apps/whitehall/app/models/bulk_upload.rb
18:  validate :attachments_must_be_valid
97:    validate :must_be_a_zip_file

apps/whitehall/app/models/statistics_announcement_date.rb
9:  validate :confirmed_date_must_be_exact

apps/worldcubeassociation.org/WcaOnRails/app/models/competition.rb
156:  validate :must_have_at_least_one_event, if: :confirmed_or_visible?
191:  validate :must_have_at_least_one_delegate, if: :confirmed_or_visible?
213:  validate :delegates_must_be_delegates, unless: :is_probably_over?
314:  validate :dates_must_be_valid
416:  validate :registration_must_close_after_it_opens

apps/worldcubeassociation.org/WcaOnRails/app/models/merge_people.rb
43:  validate :must_look_like_the_same_person
61:  validate :person2_must_not_have_associated_user

apps/worldcubeassociation.org/WcaOnRails/app/models/poll.rb
13:  validate :must_have_at_least_two_options, if: :confirmed?

apps/worldcubeassociation.org/WcaOnRails/app/models/person.rb
46:  validate :dob_must_be_in_the_past

apps/worldcubeassociation.org/WcaOnRails/app/models/registration.rb
26:  validate :competition_must_use_wca_registration
212:  validate :must_register_for_gte_one_event

apps/worldcubeassociation.org/WcaOnRails/app/models/team_member.rb
15:  validate :start_date_must_be_earlier_than_end_date

apps/worldcubeassociation.org/WcaOnRails/app/models/vote.rb
10:  validate :poll_id_must_be_valid
17:  validate :option_must_match_poll
24:  validate :must_have_at_least_one_option
31:  validate :number_of_options_must_match_poll
38:  validate :poll_must_be_confirmed
45:  validate :poll_must_still_be_open

apps/worldcubeassociation.org/WcaOnRails/app/models/user.rb
93:  validate :name_must_match_person_name
100:  validate :dob_must_be_in_the_past
287:  validate :senior_delegate_must_be_senior_delegate

apps/worldcubeassociation.org/WcaOnRails/lib/solve_time.rb
257:  validate :times_over_10_minutes_must_be_rounded

from rails-style-guide.

pirj avatar pirj commented on May 13, 2024 2

Let's look at the Rails' guide:

validate :expiration_date_cannot_be_in_the_past,
    :discount_cannot_be_greater_than_total_value

validate :active_customer, on: :create

  def expiration_date_cannot_be_in_the_past
    if expiration_date.present? && expiration_date < Date.today
      errors.add(:expiration_date, "can't be in the past")
    end
  end

I can see the following reasons for having a naming guideline for custom validators:

  • indicate that a method is used in validations and is not intended to be used as a predicate
  • make validate :... to read like a correct statement
  • make method name on its own to reflect what it does

Is there a clear way how to hit all three goals at once? Quite unlikely from my point of view, even considering that predicate methods usually end with ?.

Prefixing with validate_ at least solves 1 & 3.

from rails-style-guide.

3limin4t0r avatar 3limin4t0r commented on May 13, 2024 2

Don't forget you could completely skip this discussion if you write a custom validator.

validates :birthday, in_past: true

This might not always be the best option, but for more general things like checking if a date is in the past it's a pretty logical choice.

from rails-style-guide.

RKushnir avatar RKushnir commented on May 13, 2024 1

In my opinion, it's all down to having a convention. If I see X, and I know X is what we call custom validations, then it's clear no matter what X is. If there's no convention, neither "validate", nor "must" would tell me enough: validate_name_is_snake_case — is it just a boolean telling me whether to perform the validation or the validation itself?

So the important part that I see is to pick something that allows to easily express the intention.

Besides naming, we can also reduce the risk by keeping the validation methods private, putting them all consecutively together, maybe with a comment to separate the section of code. This should make it fool-proof.

from rails-style-guide.

Victorcorcos avatar Victorcorcos commented on May 13, 2024 1

I prefer the must prefix, because it makes the validate line more readable and less prolix

Let's look at both sentences

1

validate :name_must_be_in_the_past
# Validates name must be in the past

2

validate :validate_name_is_in_the_past
# Validates validates name is in the past

The first sentence makes much more sense

from rails-style-guide.

eliotsykes avatar eliotsykes commented on May 13, 2024

I try to follow this guidance.

Consider adding a line in the validate_ method that shows what the custom validation could look like, as a common mistake is for these methods to be written to return a boolean rather than add to the errors object - as you say in the comments in email_is_not_gmail_account.

from rails-style-guide.

eliotsykes avatar eliotsykes commented on May 13, 2024

This guidance is followed in a few open source projects, examples follow:

apps/24pullrequests/app/models/event.rb
5:  validate :validate_start_time_is_in_range, if: :start_time
6:  validate :validate_start_time_is_not_in_the_past, if: :start_time

apps/accelerated_claims/app/models/claimant.rb
17:  validate :validate_claimant_state

apps/accelerated_claims/app/models/defendant.rb
20:  validate :validate_defendant_state

apps/accelerated_claims/app/models/notice.rb
4:  validate :validate_notice_served

apps/accelerated_claims/app/models/tenancy.rb
68:    t.validate :validate_applicable_statements_confirmed

apps/alchemy_cms/lib/alchemy/essence.rb
36:          validate :validate_ingredient, :on => :update, :if => 'validations.any?'

apps/bridge_troll/app/models/event.rb
90:      validate :validate_student_rsvp_limit
99:      validate :validate_volunteer_rsvp_limit

apps/canvas-lms/app/models/account.rb
127:  validate :validate_auth_discovery_url

apps/canvas-lms/app/models/account_authorization_config.rb
83:  validate :validate_federated_attributes

apps/canvas-lms/app/models/account_notification.rb
20:  validate :validate_dates

apps/canvas-lms/app/models/communication_channel.rb
38:  validate :validate_email, if: lambda { |cc| cc.path_type == TYPE_EMAIL && cc.new_record? }

apps/canvas-lms/app/models/course_section.rb
42:  validate :validate_section_dates

apps/canvas-lms/app/models/course.rb
212:  validate :validate_course_dates
213:  validate :validate_course_image

apps/canvas-lms/app/models/developer_key.rb
40:  validate :validate_redirect_uris

apps/canvas-lms/app/models/discussion_entry.rb
49:  validate :validate_depth, on: :create

apps/canvas-lms/app/models/discussion_topic.rb
75:  validate :validate_draft_state_change, :if => :workflow_state_changed?

apps/canvas-lms/app/models/group_membership.rb
29:  validate :validate_within_group_limit

apps/canvas-lms/app/models/learning_outcome.rb
55:  validate :validate_calculation_int
56:  validate :validate_text_only_changes_when_assessed

apps/canvas-lms/app/models/quizzes/quiz.rb
54:  validate :validate_quiz_type, :if => :quiz_type_changed?
55:  validate :validate_ip_filter, :if => :ip_filter_changed?
56:  validate :validate_hide_results, :if => :hide_results_changed?
57:  validate :validate_correct_answer_visibility, :if => lambda { |quiz|

apps/canvas-lms/app/models/wiki_page.rb
52:  validate :validate_front_page_visibility

apps/canvas-lms/lib/canvas/draft_state_validations.rb
22:        validate :validate_draft_state_change, :if => :workflow_state_changed?

apps/cartodb/app/models/carto/analysis.rb
13:  validate :validate_user_not_viewer

apps/cartodb/app/models/carto/asset.rb
19:    validate :validate_storage_info, if: :storage_info

apps/cartodb/app/models/carto/data_import.rb
31:    validate :validate_collision_strategy

apps/cartodb/app/models/carto/layer.rb
90:    validate :validate_not_viewer

apps/cartodb/app/models/carto/map.rb
44:  validate :validate_options

apps/cartodb/app/models/carto/overlay.rb
14:    validate :validate_user_not_viewer

apps/cartodb/app/models/carto/user_table.rb
45:    validate :validate_user_not_viewer
49:    validate :validate_privacy_changes

apps/cartodb/app/models/carto/visualization.rb
90:  validate :validate_password_presence
91:  validate :validate_privacy_changes
92:  validate :validate_user_not_viewer, on: :create

apps/cartodb/app/models/carto/widget.rb
19:  validate :validate_user_not_viewer

apps/case_file_editor/app/models/compensation_application.rb
50:  validate :validate_defendant_names

apps/case_file_editor/app/models/domestic_violence.rb
17:  validate :validate_victim_name

apps/case_file_editor/app/models/concerns/property_id_validation.rb
12:    validate :validate_property_ids

apps/case_file_editor/app/models/defendant.rb
436:  validate :validate_by_age

apps/case_file_editor/app/models/mme_recorded_response.rb
42:  validate :validate_id

apps/case_file_editor/app/models/mme_not_recorded_response.rb
15:  validate :validate_no_mme_not_recorded_if_mme_present

apps/case_file_editor/app/models/mme.rb
55:  validate :validate_id_uniqueness

apps/case_file_editor/app/models/property.rb
53:  validate :validate_id_uniqueness

apps/case_file_editor/app/models/witness.rb
66:  validate :validate_id_uniqueness, if: :witness_id

apps/catarse/app/models/concerns/project/custom_validators.rb
11:    validate :validate_tags

apps/cloudnet/app/models/server_wizard.rb
33:  validate :validate_wallet_credit, if: :step3?
34:  validate :validate_provisioner_template, if: :step2?

apps/coursemology2/app/models/concerns/announcement_concern.rb
12:    validate :validate_start_at_cannot_be_after_end_at

apps/coursemology2/app/models/course/assessment/answer/programming_file.rb
8:  validate :validate_content_size

apps/coursemology2/app/models/course/assessment/answer/text_response.rb
8:  validate :validate_filenames_are_unique, if: :attachments_changed?

apps/coursemology2/app/models/course/assessment/answer.rb
36:  validate :validate_consistent_assessment
37:  validate :validate_assessment_state, if: :attempting?
41:  validate :validate_grade, unless: :attempting?

apps/coursemology2/app/models/course/assessment/question/multiple_response.rb
7:  validate :validate_multiple_choice_has_solution, if: :multiple_choice?

apps/coursemology2/app/models/course/assessment/question/text_response.rb
5:  validate :validate_grade

apps/coursemology2/app/models/course/assessment/question/text_response_solution.rb
6:  validate :validate_grade

apps/coursemology2/app/models/course/assessment/skill.rb
7:  validate :validate_consistent_course

apps/coursemology2/app/models/course/condition/achievement.rb
15:  validate :validate_achievement_condition, if: :achievement_id_changed?

apps/coursemology2/app/models/course/condition/assessment.rb
12:  validate :validate_assessment_condition, if: :assessment_id_changed?

apps/coursemology2/app/models/course/assessment/submission.rb
33:  validate :validate_consistent_user, :validate_unique_submission, on: :create
34:  validate :validate_awarded_attributes, if: :published?

apps/coursemology2/app/models/course/enrol_request.rb
3:  validate :validate_user_not_in_course, on: :create

apps/coursemology2/app/models/course/group.rb
15:  validate :validate_new_users_are_unique
16:  validate :validate_presence_of_group_manager, on: :update

apps/coursemology2/app/models/course/lesson_plan/item.rb
10:  validate :validate_presence_of_bonus_end_at,

apps/coursemology2/app/models/course/material.rb
10:  validate :validate_name_is_unique_among_folders

apps/coursemology2/app/models/course/material/folder.rb
16:  validate :validate_name_is_unique_among_materials

apps/coursemology2/app/models/course/video/session.rb
8:  validate :validate_start_before_end

apps/coursemology2/app/models/course/video/submission.rb
10:  validate :validate_consistent_user, :validate_unique_submission, on: :create

apps/diaspora/app/models/api/openid_connect/authorization.rb
11:      validate :validate_scope_names

apps/ds-auth/app/models/application_membership.rb
6:  validate :validate_application_available_to_user

apps/e-petitions/app/models/archived/debate_outcome.rb
25:    validate :validate_commons_image_dimensions, unless: :no_commons_image_queued

apps/e-petitions/app/models/debate_outcome.rb
22:  validate :validate_commons_image_dimensions, unless: :no_commons_image_queued

apps/errbit/app/models/issue_tracker.rb
10:  validate :validate_tracker

apps/foreman/app/models/auth_sources/auth_source_ldap.rb
38:  validate :validate_ldap_filter, :unless => Proc.new { |auth| auth.ldap_filter.blank? }

apps/foreman/app/models/concerns/hostext/ownership.rb
14:      validate :validate_owner

apps/foreman/app/models/concerns/parameter_validators.rb
6:    validate :validate_parameters_names

apps/foreman/app/models/concerns/pxe_loader_validator.rb
5:    validate :validate_pxe_loader

apps/foreman/app/models/concerns/user_time.rb
5:    validate :validate_timezone

apps/foreman/app/models/hostgroup.rb
13:  validate :validate_subnet_types

apps/foreman/app/models/lookup_keys/variable_lookup_key.rb
7:  validate :validate_default_value, :disable_merge_overrides, :disable_avoid_duplicates, :disable_merge_default

apps/foreman/app/models/lookup_value.rb
16:  validate :validate_value, :unless => Proc.new{|p| p.omit }

apps/foreman/app/models/lookup_keys/puppetclass_lookup_key.rb
8:  validate :validate_default_value, :disable_merge_overrides, :disable_avoid_duplicates, :disable_merge_default, :if => :override?

apps/foreman/app/models/nic/bmc.rb
8:    validate :validate_bmc_proxy

apps/foreman/app/models/nic/base.rb
21:    validate :validate_mac_is_unicast,
37:    validate :validate_subnet_types

apps/foreman/app/models/setting.rb
45:  validate :validate_host_owner, :if => Proc.new {|s| s.name == "host_owner" }
55:  validate :validate_frozen_attributes

apps/foreman/app/models/subnet/ipv6.rb
11:  validate :validate_eui64_prefix_length, :if => Proc.new { |subnet| subnet.ipam == IPAM::MODES[:eui64]}

apps/foreman/app/models/subnet.rb
76:  validate :validate_ranges

apps/gitlabhq/app/models/merge_request.rb
98:  validate :validate_branches, unless: [:allow_broken, :importing?, :closed_without_fork?]
99:  validate :validate_fork, unless: :closed_without_fork?
100:  validate :validate_target_project, on: :create

apps/gitlabhq/app/models/pages_domain.rb
9:  validate :validate_pages_domain
10:  validate :validate_matching_key, if: ->(domain) { domain.certificate.present? || domain.key.present? }
11:  validate :validate_intermediates, if: ->(domain) { domain.certificate.present? }

apps/gitlabhq/app/models/personal_access_token.rb
18:  validate :validate_scopes

apps/hours/app/models/signup.rb
13:  validate :validate_children

apps/huginn/app/concerns/email_concern.rb
7:    self.validate :validate_email_options

apps/huginn/app/concerns/agent_controller_concern.rb
5:    validate :validate_control_action

apps/huginn/app/concerns/assignable_types.rb
5:    validate :validate_type

apps/huginn/app/concerns/evernote_concern.rb
7:    validate :validate_evernote_options

apps/huginn/app/concerns/sortable_events.rb
5:    validate :validate_events_order

apps/huginn/app/concerns/liquid_interpolatable.rb
7:    validate :validate_interpolation

apps/huginn/app/concerns/twitter_concern.rb
7:    validate :validate_twitter_options

apps/huginn/app/concerns/weibo_concern.rb
7:    self.validate :validate_weibo_options

apps/huginn/app/importers/scenario_import.rb
20:  validate :validate_presence_of_file_url_or_data
22:  validate :validate_data

apps/huginn/app/models/agent.rb
36:  validate :validate_schedule
37:  validate :validate_options

apps/jobsworth/app/models/abstract_task.rb
63:  validate :validate_properties

apps/jobsworth/app/models/custom_attribute_value.rb
6:  validate :validate_custom_attribute

apps/jobsworth/app/models/customer.rb
33:  validate :validate_custom_attributes

apps/jobsworth/app/models/organizational_unit.rb
13:  validate :validate_custom_attributes

apps/jobsworth/app/models/resource.rb
21:  validate :validate_attributes

apps/jobsworth/app/models/user.rb
78:  validate :validate_custom_attributes

apps/jobsworth/app/models/work_log.rb
32:  validate :validate_logs

apps/katello/app/models/katello/content_view_filter.rb
22:    validate :validate_content_view
23:    validate :validate_repos

apps/katello/app/models/katello/event.rb
3:    validate :validate_event_type

apps/katello/app/models/katello/host_collection_hosts.rb
6:    validate :validate_max_hosts_not_exceeded

apps/katello/app/models/katello/sync_plan.rb
23:    validate :validate_sync_date

apps/locomotivecms-engine/app/models/locomotive/concerns/site/metafields.rb
16:          validate :validate_metafields_schema

apps/loomio/app/models/concerns/group_privacy.rb
10:    validate :validate_parent_members_can_see_discussions
11:    validate :validate_is_visible_to_parent_members
12:    validate :validate_discussion_privacy_options

apps/loomio/app/models/membership_request.rb
5:  validate :validate_not_in_group_already
6:  validate :validate_unique_membership_request

apps/manageiq/app/models/classification.rb
24:  validate :validate_format_of_name
26:  validate :validate_uniqueness_on_tag_name

apps/manageiq/app/models/dialog.rb
8:  validate :validate_children

apps/manageiq/app/models/dialog_group.rb
5:  validate :validate_children

apps/manageiq/app/models/dialog_tab.rb
5:  validate :validate_children

apps/manageiq/app/models/endpoint.rb
10:  validate :validate_certificate_authority

apps/manageiq/app/models/miq_alert.rb
9:  validate :validate_automate_expressions

apps/manageiq/app/models/miq_group.rb
23:  validate :validate_default_tenant, :on => :update, :if => :tenant_id_changed?

apps/manageiq/app/models/miq_request.rb
29:  validate :validate_class, :validate_request_type

apps/manageiq/app/models/service_reconfigure_task.rb
2:  validate :validate_request_type, :validate_state

apps/manageiq/app/models/service_template_provision_task.rb
2:  validate :validate_request_type, :validate_state

apps/manageiq/app/models/tenant.rb
45:  validate :validate_default_tenant, :on => :update, :if => :default_miq_group_id_changed?

apps/manageiq/app/models/vm_migrate_task.rb
4:  validate :validate_request_type, :validate_state

apps/manageiq/app/models/vm_reconfigure_task.rb
4:  validate :validate_request_type, :validate_state

apps/netguru-people/app/models/membership.rb
12:  validate :validate_starts_at_ends_at
13:  validate :validate_duplicate_project

apps/onebody/app/models/custom_field_value.rb
10:  validate :validate_value_format

apps/onebody/app/models/friendship_request.rb
11:  validate :validate_email_on_target
17:  validate :validate_friends_enabled_on_target

apps/onebody/app/models/group.rb
51:  validate :validate_self_referencing_parents_of
59:  validate :validate_attendance_enabled_for_checkin_destinations

apps/onebody/app/models/membership.rb
22:  validate :validate_roles

apps/onebody/app/models/membership_request.rb
16:  validate :validate_duplicate_membership

apps/onebody/app/models/person.rb
69:  validate :validate_password_length
70:  validate :validate_password_strength
107:  validate :validate_email_unique

apps/onebody/app/models/signup.rb
13:  validate :validate_adult
14:  validate :validate_not_a_bot
15:  validate :validate_sign_up_allowed

apps/onebody/app/models/verification.rb
13:  validate :validate_max_attempts, on: :create
14:  validate :validate_people, if: -> { email || mobile_phone }
15:  validate :validate_people_able_to_sign_in, if: -> { email || mobile_phone }

apps/open-build-service/src/api/app/models/attrib.rb
34:  validate :validate_value_count,

apps/open-build-service/src/api/app/models/comment.rb
10:  validate :validate_parent_id

apps/open-build-service/src/api/app/models/flag.rb
20:  validate :validate_custom_save
27:  validate :validate_duplicates, on: :create

apps/open-build-service/src/api/app/models/groups_user.rb
7:  validate :validate_duplicates
11:  validate :validate_duplicates, on: :create

apps/open-build-service/src/api/app/models/group_maintainer.rb
7:  validate :validate_duplicates
11:  validate :validate_duplicates, on: :create

apps/open-build-service/src/api/app/models/linked_project.rb
5:  validate :validate_duplicates

apps/open-build-service/src/api/app/models/review.rb
22:  validate :validate_non_symmetric_assignment
23:  validate :validate_not_self_assigned

apps/openproject/app/models/custom_field.rb
58:  validate :validate_default_value
59:  validate :validate_regex

apps/openproject/app/models/custom_value.rb
35:  validate :validate_presence_of_required_value
36:  validate :validate_format_of_value
37:  validate :validate_type_of_value
38:  validate :validate_length_of_value

apps/openproject/app/models/message.rb
83:  validate :validate_unlocked_root, on: :create

apps/openproject/app/models/member_role.rb
38:  validate :validate_project_member_role

apps/openproject/app/models/member.rb
40:  validate :validate_presence_of_role
41:  validate :validate_presence_of_principal

apps/openproject/app/models/queries/filters/base.rb
117:  validate :validate_inclusion_of_operator,

apps/openproject/app/models/query.rb
47:  validate :validate_work_package_filters
48:  validate :validate_columns
49:  validate :validate_sort_criteria
50:  validate :validate_group_by
51:  validate :validate_show_hierarchies

apps/openproject/app/models/relation.rb
96:  validate :validate_sanity_of_relation,

apps/openproject/app/models/repository.rb
50:  validate :validate_enabled_scm, on: :create

apps/openproject/app/models/system_user.rb
35:  validate :validate_unique_system_user, on: :create

apps/openproject/app/models/time_entry.rb
52:  validate :validate_hours_are_in_range
53:  validate :validate_project_is_set
54:  validate :validate_consistency_of_work_package_id

apps/openproject/app/models/type/attribute_groups.rb
34:    validate :validate_attribute_group_names
35:    validate :validate_attribute_groups

apps/openproject/app/models/timeline.rb
53:  validate :validate_option_dates
54:  validate :validate_option_numeric

apps/openproject/app/models/user.rb
846:  validate :validate_unique_anonymous_user, on: :create
874:  validate :validate_unique_deleted_user, on: :create

apps/openproject/app/models/watcher.rb
37:  validate :validate_active_user
38:  validate :validate_user_allowed_to_watch

apps/openproject/app/models/version.rb
52:  validate :validate_start_date_before_effective_date

apps/openproject/app/models/wiki_page.rb
62:  validate :validate_consistency_of_parent_title
63:  validate :validate_non_circular_dependency
64:  validate :validate_same_project

apps/openproject/app/models/work_package/validations.rb
51:    validate :validate_start_date_before_soonest_start_date
52:    validate :validate_fixed_version_is_assignable, unless: :skip_fixed_version_validation?
53:    validate :validate_fixed_version_is_still_open, unless: :skip_fixed_version_validation?
54:    validate :validate_enabled_type
56:    validate :validate_milestone_constraint
57:    validate :validate_parent_constraint
59:    validate :validate_status_transition
61:    validate :validate_active_priority
63:    validate :validate_category
65:    validate :validate_descendants, unless: :skip_descendants_validation
67:    validate :validate_estimated_hours

apps/openproject/lib/open_project/nested_set/root_id_handling.rb
59:        validate :validate_correct_parent

apps/openproject/lib/plugins/acts_as_customizable/lib/acts_as_customizable.rb
50:          validate :validate_custom_values

apps/openstreetmap-website/app/models/node.rb
40:  validate :validate_position

apps/openstreetmap-website/app/models/note.rb
12:  validate :validate_position

apps/openstreetmap-website/app/models/old_node.rb
21:  validate :validate_position

apps/planningalerts/app/models/alert.rb
5:  validate :validate_address

apps/postal/app/models/additional_route_endpoint.rb
18:  validate :validate_endpoint_belongs_to_server
19:  validate :validate_wildcard
20:  validate :validate_uniqueness

apps/postal/app/models/ip_pool_rule.rb
23:  validate :validate_from_and_to_addresses
24:  validate :validate_ip_pool_belongs_to_organization

apps/postal/app/models/organization_user.rb
19:  validate :validate_uniqueness

apps/postal/app/models/route.rb
41:  validate :validate_route_is_routed
42:  validate :validate_domain_belongs_to_server
43:  validate :validate_endpoint_belongs_to_server
44:  validate :validate_name_uniqueness
45:  validate :validate_return_path_route_endpoints
46:  validate :validate_no_additional_routes_on_non_endpoint_route

apps/postal/app/models/server.rb
78:  validate :validate_ip_pool_belongs_to_organization

apps/postal/app/models/track_domain.rb
32:  validate :validate_domain_belongs_to_server

apps/prison-visits/app/models/feedback.rb
11:  validate :validate_email, if: ->(f) { f.email.present? }

apps/prison-visits/app/models/concerns/person.rb
18:    validate :validate_four_digit_year

apps/prison-visits/app/models/confirmation.rb
25:  validate :validate_outcome
26:  validate :validate_reference
27:  validate :validate_renewals
28:  validate :validate_unlisted_visitors
29:  validate :validate_banned_visitors

apps/prison-visits/app/models/visit.rb
19:  validate :validate_amount_of_adults, on: :visitors_set

apps/prison-visits/app/models/visitor.rb
17:  validate :validate_email, if: :primary?

apps/publisher/app/models/artefact.rb
117:  validate :validate_prefixes_and_paths

apps/redmine/app/models/auth_source_ldap.rb
36:  validate :validate_filter

apps/redmine/app/models/attachment.rb
30:  validate :validate_max_file_size, :validate_file_extension

apps/redmine/app/models/board.rb
30:  validate :validate_board

apps/redmine/app/models/custom_field.rb
37:  validate :validate_custom_field

apps/redmine/app/models/group_builtin.rb
19:  validate :validate_uniqueness, :on => :create

apps/redmine/app/models/issue.rb
71:  validate :validate_issue, :validate_required_fields, :validate_permissions

apps/redmine/app/models/issue_relation.rb
73:  validate :validate_issue_relation

apps/redmine/app/models/member.rb
27:  validate :validate_role

apps/redmine/app/models/principal.rb
37:  validate :validate_status

apps/redmine/app/models/member_role.rb
28:  validate :validate_role_member

apps/redmine/app/models/project.rb
79:  validate :validate_parent

apps/redmine/app/models/query.rb
220:  validate :validate_query_filters

apps/redmine/app/models/repository.rb
50:  validate :validate_repository_path

apps/redmine/app/models/time_entry.rb
49:  validate :validate_time_entry

apps/redmine/app/models/user.rb
113:  validate :validate_password_length
923:  validate :validate_anonymous_uniqueness, :on => :create

apps/redmine/app/models/watcher.rb
24:  validate :validate_user

apps/redmine/app/models/wiki_page.rb
51:  validate :validate_parent_title

apps/redmine/app/models/workflow_permission.rb
21:  validate :validate_field_name

apps/redmine/lib/plugins/acts_as_customizable/lib/acts_as_customizable.rb
37:          validate :validate_custom_field_values

apps/reservations/app/models/announcement.rb
6:  validate :validate_end_date_before_start_date

apps/reservations/app/models/blackout.rb
11:  validate :validate_end_date_before_start_date

apps/ror_ecommerce/app/models/image.rb
33:  validate :validate_photo

apps/ror_ecommerce/app/models/referral.rb
15:  validate :validate_has_not_signed_up_yet

apps/samson/app/models/build.rb
20:  validate :validate_git_reference, on: :create

apps/samson/app/models/concerns/permalinkable.rb
8:    validate :validate_unique_permalink

apps/samson/app/models/deploy_group.rb
20:  validate :validate_vault_server_has_same_environment

apps/samson/app/models/deploy.rb
14:  validate :validate_stage_is_unlocked, on: :create
15:  validate :validate_stage_uses_deploy_groups_properly, on: :create

apps/samson/app/models/job.rb
14:  validate :validate_globally_unlocked

apps/samson/app/models/project.rb
11:  validate :validate_can_release

apps/samson/app/models/stage.rb
35:  validate :validate_deploy_group_selected

apps/samson/lib/samson/secrets/vault_server.rb
46:      validate :validate_cert
47:      validate :validate_connection

apps/samson/plugins/env/app/models/concerns/accepts_environment_variables.rb
9:      validate :validate_unique_environment_variables

apps/samson/plugins/kubernetes/app/decorators/stage_decorator.rb
3:  validate :validate_deploy_groups_have_a_cluster, if: :kubernetes

apps/samson/plugins/kubernetes/app/models/kubernetes/cluster_deploy_group.rb
12:    validate :validate_namespace_exists

apps/samson/plugins/kubernetes/app/models/kubernetes/release_doc.rb
16:    validate :validate_config_file, on: :create

apps/samson/plugins/kubernetes/app/models/kubernetes/release.rb
14:    validate :validate_docker_image_in_registry, on: :create

apps/samson/plugins/slack_webhooks/app/models/slack_webhook.rb
4:  validate :validate_url
5:  validate :validate_used

apps/scumblr/app/models/task.rb
34:  validate :validate_search

apps/signonotron2/app/models/event_log.rb
52:  validate :validate_event_mappable

apps/signonotron2/lib/devise/models/password_archivable.rb
18:        validate :validate_password_archive

apps/solidus/core/app/models/spree/reimbursement.rb
14:    validate :validate_return_items_belong_to_same_order

apps/solidus/core/app/models/spree/return_item.rb
42:    validate :validate_acceptance_status_for_reimbursement
44:    validate :validate_no_other_completed_return_items

apps/spree/core/app/models/spree/reimbursement.rb
20:    validate :validate_return_items_belong_to_same_order

apps/spree/core/app/models/spree/return_item.rb
37:    validate :validate_acceptance_status_for_reimbursement
39:    validate :validate_no_other_completed_return_items, on: :create

apps/tracks/app/models/user.rb
108:  validate :validate_auth_type

apps/verboice/app/models/external_service_step.rb
32:  validate :validate_variables

apps/verboice/app/models/schedule.rb
31:  validate :validate_retries

apps/whitehall/app/models/consultation.rb
14:  validate :validate_closes_after_opens

apps/whitehall/app/models/historical_account.rb
11:  validate :validate_correct_political_party

apps/wiki_edu_dashboard/app/models/campaign.rb
43:  validate :validate_dates

apps/worldcubeassociation.org/WcaOnRails/app/models/result.rb
24:  validate :validate_each_solve, if: :event
33:  validate :validate_solve_count, if: :event
41:  validate :validate_average
49:  validate :validate_best, if: :event

engines/blazer/app/models/blazer/check.rb
7:    validate :validate_emails
8:    validate :validate_variables, if: -> { query_id_changed? }

engines/thredded/app/forms/thredded/topic_form.rb
10:    validate :validate_children

engines/thredded/app/forms/thredded/private_topic_form.rb
22:    validate :validate_children

engines/thredded/app/forms/thredded/user_preferences_form.rb
10:    validate :validate_children

engines/tolk/app/models/tolk/translation.rb
9:    validate :validate_text_not_nil, :if => proc {|r| r.primary.blank? && !r.explicit_nil && !r.boolean?}

from rails-style-guide.

yjukaku avatar yjukaku commented on May 13, 2024

Thanks for the list of repos! I don't think adding a sample implementation would help in the description though as I think that might confuse the reader. 👍

from rails-style-guide.

eliotsykes avatar eliotsykes commented on May 13, 2024

Yep fair enough I can see that being a distraction

from rails-style-guide.

willisplummer avatar willisplummer commented on May 13, 2024

Has there been any progress here? If not, I'd be happy to write a rule!

from rails-style-guide.

pirj avatar pirj commented on May 13, 2024

@yjukaku Would you like to send a pull request and add this as a guideline?

from rails-style-guide.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.