diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 93c41d3..4a57cb0 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -17,4 +17,4 @@ jobs: env: COVERAGE: true RAILS_ENV: test - run: docker-compose --file docker-compose.ci.yml run ci + run: docker compose --file docker-compose.ci.yml run ci diff --git a/.rubocop.yml b/.rubocop.yml index 256b6a9..09544de 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -1,10 +1,16 @@ AllCops: + SuggestExtensions: false Exclude: - db/**/* - config/**/* - node_modules/**/* - bin/* - vendor/**/* + NewCops: enable + TargetRubyVersion: "3.2" + +Metrics/PerceivedComplexity: + Enabled: false Bundler/OrderedGems: Enabled: false @@ -14,60 +20,60 @@ Naming/AccessorMethodName: Enabled: false Style/Alias: - Description: 'Use alias_method instead of alias.' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#alias-method' + Description: "Use alias_method instead of alias." + StyleGuide: "https://github.com/bbatsov/ruby-style-guide#alias-method" Enabled: false Style/ArrayJoin: - Description: 'Use Array#join instead of Array#*.' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#array-join' + Description: "Use Array#join instead of Array#*." + StyleGuide: "https://github.com/bbatsov/ruby-style-guide#array-join" Enabled: false Style/AsciiComments: - Description: 'Use only ascii symbols in comments.' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#english-comments' + Description: "Use only ascii symbols in comments." + StyleGuide: "https://github.com/bbatsov/ruby-style-guide#english-comments" Enabled: false Naming/AsciiIdentifiers: - Description: 'Use only ascii symbols in identifiers.' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#english-identifiers' + Description: "Use only ascii symbols in identifiers." + StyleGuide: "https://github.com/bbatsov/ruby-style-guide#english-identifiers" Enabled: false Style/Attr: - Description: 'Checks for uses of Module#attr.' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#attr' + Description: "Checks for uses of Module#attr." + StyleGuide: "https://github.com/bbatsov/ruby-style-guide#attr" Enabled: false Metrics/BlockNesting: - Description: 'Avoid excessive block nesting' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#three-is-the-number-thou-shalt-count' + Description: "Avoid excessive block nesting" + StyleGuide: "https://github.com/bbatsov/ruby-style-guide#three-is-the-number-thou-shalt-count" Enabled: false Style/CaseEquality: - Description: 'Avoid explicit use of the case equality operator(===).' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-case-equality' + Description: "Avoid explicit use of the case equality operator(===)." + StyleGuide: "https://github.com/bbatsov/ruby-style-guide#no-case-equality" Enabled: false Style/CharacterLiteral: - Description: 'Checks for uses of character literals.' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-character-literals' + Description: "Checks for uses of character literals." + StyleGuide: "https://github.com/bbatsov/ruby-style-guide#no-character-literals" Enabled: false Style/ClassAndModuleChildren: - Description: 'Checks style of children classes and modules.' + Description: "Checks style of children classes and modules." Enabled: false Metrics/ClassLength: - Description: 'Avoid classes longer than 100 lines of code.' + Description: "Avoid classes longer than 100 lines of code." Enabled: false Metrics/ModuleLength: - Description: 'Avoid modules longer than 100 lines of code.' + Description: "Avoid modules longer than 100 lines of code." Enabled: false Style/ClassVars: - Description: 'Avoid the use of class variables.' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-class-vars' + Description: "Avoid the use of class variables." + StyleGuide: "https://github.com/bbatsov/ruby-style-guide#no-class-vars" Enabled: false Style/CollectionMethods: @@ -79,27 +85,26 @@ Style/CollectionMethods: find_all: select Style/ColonMethodCall: - Description: 'Do not use :: for method call.' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#double-colons' + Description: "Do not use :: for method call." + StyleGuide: "https://github.com/bbatsov/ruby-style-guide#double-colons" Enabled: false Style/CommentAnnotation: Description: >- - Checks formatting of special comments - (TODO, FIXME, OPTIMIZE, HACK, REVIEW). - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#annotate-keywords' + Checks formatting of special comments + (TODO, FIXME, OPTIMIZE, HACK, REVIEW). + StyleGuide: "https://github.com/bbatsov/ruby-style-guide#annotate-keywords" Enabled: false Metrics/AbcSize: Description: >- - A calculated magnitude based on number of assignments, - branches, and conditions. + A calculated magnitude based on number of assignments, + branches, and conditions. Enabled: false Metrics/BlockLength: - CountComments: true # count full line comments? + CountComments: true # count full line comments? Max: 40 - ExcludedMethods: [elastic_query_parameters, parameters] Exclude: - "spec/**/*" - "db/migrate/*" @@ -109,31 +114,31 @@ Metrics/BlockLength: Metrics/CyclomaticComplexity: Description: >- - A complexity metric that is strongly correlated to the number - of test cases needed to validate a method. + A complexity metric that is strongly correlated to the number + of test cases needed to validate a method. Enabled: false Style/PreferredHashMethods: - Description: 'Checks use of `has_key?` and `has_value?` Hash methods.' - StyleGuide: '#hash-key' + Description: "Checks use of `has_key?` and `has_value?` Hash methods." + StyleGuide: "#hash-key" Enabled: false Style/Documentation: - Description: 'Document classes and non-namespace modules.' + Description: "Document classes and non-namespace modules." Enabled: false Style/DoubleNegation: - Description: 'Checks for uses of double negation (!!).' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-bang-bang' + Description: "Checks for uses of double negation (!!)." + StyleGuide: "https://github.com/bbatsov/ruby-style-guide#no-bang-bang" Enabled: false Style/EachWithObject: - Description: 'Prefer `each_with_object` over `inject` or `reduce`.' + Description: "Prefer `each_with_object` over `inject` or `reduce`." Enabled: false Style/EmptyLiteral: - Description: 'Prefer literals to Array.new/Hash.new/String.new.' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#literal-array-hash' + Description: "Prefer literals to Array.new/Hash.new/String.new." + StyleGuide: "https://github.com/bbatsov/ruby-style-guide#literal-array-hash" Enabled: false # Checks whether the source file has a utf-8 encoding comment or not @@ -143,13 +148,13 @@ Style/Encoding: Enabled: false Style/EvenOdd: - Description: 'Favor the use of Fixnum#even? && Fixnum#odd?' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#predicate-methods' + Description: "Favor the use of Fixnum#even? && Fixnum#odd?" + StyleGuide: "https://github.com/bbatsov/ruby-style-guide#predicate-methods" Enabled: false Naming/FileName: - Description: 'Use snake_case for source file names.' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#snake-case-files' + Description: "Use snake_case for source file names." + StyleGuide: "https://github.com/bbatsov/ruby-style-guide#snake-case-files" Enabled: false Style/FrozenStringLiteralComment: @@ -159,192 +164,192 @@ Style/FrozenStringLiteralComment: Enabled: false Lint/FlipFlop: - Description: 'Checks for flip flops' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-flip-flops' + Description: "Checks for flip flops" + StyleGuide: "https://github.com/bbatsov/ruby-style-guide#no-flip-flops" Enabled: false Style/FormatString: - Description: 'Enforce the use of Kernel#sprintf, Kernel#format or String#%.' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#sprintf' + Description: "Enforce the use of Kernel#sprintf, Kernel#format or String#%." + StyleGuide: "https://github.com/bbatsov/ruby-style-guide#sprintf" Enabled: false Style/GlobalVars: - Description: 'Do not introduce global variables.' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#instance-vars' - Reference: 'http://www.zenspider.com/Languages/Ruby/QuickRef.html' + Description: "Do not introduce global variables." + StyleGuide: "https://github.com/bbatsov/ruby-style-guide#instance-vars" + Reference: "http://www.zenspider.com/Languages/Ruby/QuickRef.html" Enabled: false Style/GuardClause: - Description: 'Check for conditionals that can be replaced with guard clauses' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-nested-conditionals' + Description: "Check for conditionals that can be replaced with guard clauses" + StyleGuide: "https://github.com/bbatsov/ruby-style-guide#no-nested-conditionals" Enabled: false Style/IfUnlessModifier: Description: >- - Favor modifier if/unless usage when you have a - single-line body. - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#if-as-a-modifier' + Favor modifier if/unless usage when you have a + single-line body. + StyleGuide: "https://github.com/bbatsov/ruby-style-guide#if-as-a-modifier" Enabled: false Style/IfWithSemicolon: - Description: 'Do not use if x; .... Use the ternary operator instead.' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-semicolon-ifs' + Description: "Do not use if x; .... Use the ternary operator instead." + StyleGuide: "https://github.com/bbatsov/ruby-style-guide#no-semicolon-ifs" Enabled: false Style/InlineComment: - Description: 'Avoid inline comments.' + Description: "Avoid inline comments." Enabled: false Style/Lambda: - Description: 'Use the new lambda literal syntax for single-line blocks.' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#lambda-multi-line' + Description: "Use the new lambda literal syntax for single-line blocks." + StyleGuide: "https://github.com/bbatsov/ruby-style-guide#lambda-multi-line" Enabled: false Style/LambdaCall: - Description: 'Use lambda.call(...) instead of lambda.(...).' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#proc-call' + Description: "Use lambda.call(...) instead of lambda.(...)." + StyleGuide: "https://github.com/bbatsov/ruby-style-guide#proc-call" Enabled: false Style/LineEndConcatenation: Description: >- - Use \ instead of + or << to concatenate two string literals at - line end. + Use \ instead of + or << to concatenate two string literals at + line end. Enabled: false Layout/LineLength: - Description: 'Limit lines to 80 characters.' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#80-character-limits' + Description: "Limit lines to 80 characters." + StyleGuide: "https://github.com/bbatsov/ruby-style-guide#80-character-limits" Max: 140 Metrics/MethodLength: - Description: 'Avoid methods longer than 10 lines of code.' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#short-methods' + Description: "Avoid methods longer than 10 lines of code." + StyleGuide: "https://github.com/bbatsov/ruby-style-guide#short-methods" Enabled: false Style/ModuleFunction: - Description: 'Checks for usage of `extend self` in modules.' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#module-function' + Description: "Checks for usage of `extend self` in modules." + StyleGuide: "https://github.com/bbatsov/ruby-style-guide#module-function" Enabled: false Style/MultilineBlockChain: - Description: 'Avoid multi-line chains of blocks.' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#single-line-blocks' + Description: "Avoid multi-line chains of blocks." + StyleGuide: "https://github.com/bbatsov/ruby-style-guide#single-line-blocks" Enabled: false Style/NegatedIf: Description: >- - Favor unless over if for negative conditions - (or control flow or). - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#unless-for-negatives' + Favor unless over if for negative conditions + (or control flow or). + StyleGuide: "https://github.com/bbatsov/ruby-style-guide#unless-for-negatives" Enabled: false Style/NegatedWhile: - Description: 'Favor until over while for negative conditions.' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#until-for-negatives' + Description: "Favor until over while for negative conditions." + StyleGuide: "https://github.com/bbatsov/ruby-style-guide#until-for-negatives" Enabled: false Style/Next: - Description: 'Use `next` to skip iteration instead of a condition at the end.' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-nested-conditionals' + Description: "Use `next` to skip iteration instead of a condition at the end." + StyleGuide: "https://github.com/bbatsov/ruby-style-guide#no-nested-conditionals" Enabled: false Style/NilComparison: - Description: 'Prefer x.nil? to x == nil.' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#predicate-methods' + Description: "Prefer x.nil? to x == nil." + StyleGuide: "https://github.com/bbatsov/ruby-style-guide#predicate-methods" Enabled: false Style/Not: - Description: 'Use ! instead of not.' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#bang-not-not' + Description: "Use ! instead of not." + StyleGuide: "https://github.com/bbatsov/ruby-style-guide#bang-not-not" Enabled: false Style/NumericLiterals: Description: >- - Add underscores to large numeric literals to improve their - readability. - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#underscores-in-numerics' + Add underscores to large numeric literals to improve their + readability. + StyleGuide: "https://github.com/bbatsov/ruby-style-guide#underscores-in-numerics" Enabled: false Style/OneLineConditional: Description: >- - Favor the ternary operator(?:) over - if/then/else/end constructs. - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#ternary-operator' + Favor the ternary operator(?:) over + if/then/else/end constructs. + StyleGuide: "https://github.com/bbatsov/ruby-style-guide#ternary-operator" Enabled: false Naming/BinaryOperatorParameterName: - Description: 'When defining binary operators, name the argument other.' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#other-arg' + Description: "When defining binary operators, name the argument other." + StyleGuide: "https://github.com/bbatsov/ruby-style-guide#other-arg" Enabled: false Metrics/ParameterLists: - Description: 'Avoid parameter lists longer than three or four parameters.' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#too-many-params' + Description: "Avoid parameter lists longer than three or four parameters." + StyleGuide: "https://github.com/bbatsov/ruby-style-guide#too-many-params" Enabled: false Style/PercentLiteralDelimiters: - Description: 'Use `%`-literal delimiters consistently' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#percent-literal-braces' + Description: "Use `%`-literal delimiters consistently" + StyleGuide: "https://github.com/bbatsov/ruby-style-guide#percent-literal-braces" Enabled: false Style/PerlBackrefs: - Description: 'Avoid Perl-style regex back references.' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-perl-regexp-last-matchers' + Description: "Avoid Perl-style regex back references." + StyleGuide: "https://github.com/bbatsov/ruby-style-guide#no-perl-regexp-last-matchers" Enabled: false Naming/PredicateName: - Description: 'Check the names of predicate methods.' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#bool-methods-qmark' + Description: "Check the names of predicate methods." + StyleGuide: "https://github.com/bbatsov/ruby-style-guide#bool-methods-qmark" ForbiddenPrefixes: - is_ Exclude: - spec/**/* Style/Proc: - Description: 'Use proc instead of Proc.new.' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#proc' + Description: "Use proc instead of Proc.new." + StyleGuide: "https://github.com/bbatsov/ruby-style-guide#proc" Enabled: false Style/RaiseArgs: - Description: 'Checks the arguments passed to raise/fail.' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#exception-class-messages' + Description: "Checks the arguments passed to raise/fail." + StyleGuide: "https://github.com/bbatsov/ruby-style-guide#exception-class-messages" Enabled: false Style/RegexpLiteral: - Description: 'Use / or %r around regular expressions.' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#percent-r' + Description: "Use / or %r around regular expressions." + StyleGuide: "https://github.com/bbatsov/ruby-style-guide#percent-r" Enabled: false Style/SelfAssignment: Description: >- - Checks for places where self-assignment shorthand should have - been used. - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#self-assignment' + Checks for places where self-assignment shorthand should have + been used. + StyleGuide: "https://github.com/bbatsov/ruby-style-guide#self-assignment" Enabled: false Style/SingleLineBlockParams: - Description: 'Enforces the names of some block params.' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#reduce-blocks' + Description: "Enforces the names of some block params." + StyleGuide: "https://github.com/bbatsov/ruby-style-guide#reduce-blocks" Enabled: false Style/SingleLineMethods: - Description: 'Avoid single-line methods.' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-single-line-methods' + Description: "Avoid single-line methods." + StyleGuide: "https://github.com/bbatsov/ruby-style-guide#no-single-line-methods" Enabled: false Style/SignalException: - Description: 'Checks for proper usage of fail and raise.' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#fail-method' + Description: "Checks for proper usage of fail and raise." + StyleGuide: "https://github.com/bbatsov/ruby-style-guide#fail-method" Enabled: false Style/SpecialGlobalVars: - Description: 'Avoid Perl-style global variables.' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-cryptic-perlisms' + Description: "Avoid Perl-style global variables." + StyleGuide: "https://github.com/bbatsov/ruby-style-guide#no-cryptic-perlisms" Enabled: false Style/StringLiterals: - Description: 'Checks if uses of quotes match the configured preference.' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#consistent-string-literals' + Description: "Checks if uses of quotes match the configured preference." + StyleGuide: "https://github.com/bbatsov/ruby-style-guide#consistent-string-literals" EnforcedStyle: single_quotes Enabled: true @@ -352,8 +357,8 @@ Style/SymbolArray: EnforcedStyle: brackets Style/TrailingCommaInArguments: - Description: 'Checks for trailing comma in argument lists.' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-trailing-array-commas' + Description: "Checks for trailing comma in argument lists." + StyleGuide: "https://github.com/bbatsov/ruby-style-guide#no-trailing-array-commas" EnforcedStyleForMultiline: comma SupportedStylesForMultiline: - comma @@ -362,8 +367,8 @@ Style/TrailingCommaInArguments: Enabled: true Style/TrailingCommaInArrayLiteral: - Description: 'Checks for trailing comma in array literals.' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-trailing-array-commas' + Description: "Checks for trailing comma in array literals." + StyleGuide: "https://github.com/bbatsov/ruby-style-guide#no-trailing-array-commas" EnforcedStyleForMultiline: comma SupportedStylesForMultiline: - comma @@ -372,8 +377,8 @@ Style/TrailingCommaInArrayLiteral: Enabled: true Style/TrailingCommaInHashLiteral: - Description: 'Checks for trailing comma in hash literals.' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-trailing-array-commas' + Description: "Checks for trailing comma in hash literals." + StyleGuide: "https://github.com/bbatsov/ruby-style-guide#no-trailing-array-commas" EnforcedStyleForMultiline: comma SupportedStylesForMultiline: - comma @@ -382,38 +387,38 @@ Style/TrailingCommaInHashLiteral: Enabled: true Style/TrivialAccessors: - Description: 'Prefer attr_* methods to trivial readers/writers.' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#attr_family' + Description: "Prefer attr_* methods to trivial readers/writers." + StyleGuide: "https://github.com/bbatsov/ruby-style-guide#attr_family" Enabled: false Style/VariableInterpolation: Description: >- - Don't interpolate global, instance and class variables - directly in strings. - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#curlies-interpolate' + Don't interpolate global, instance and class variables + directly in strings. + StyleGuide: "https://github.com/bbatsov/ruby-style-guide#curlies-interpolate" Enabled: false Style/WhenThen: - Description: 'Use when x then ... for one-line cases.' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#one-line-cases' + Description: "Use when x then ... for one-line cases." + StyleGuide: "https://github.com/bbatsov/ruby-style-guide#one-line-cases" Enabled: false Style/WhileUntilModifier: Description: >- - Favor modifier while/until usage when you have a - single-line body. - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#while-as-a-modifier' + Favor modifier while/until usage when you have a + single-line body. + StyleGuide: "https://github.com/bbatsov/ruby-style-guide#while-as-a-modifier" Enabled: false Style/WordArray: - Description: 'Use %w or %W for arrays of words.' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#percent-w' + Description: "Use %w or %W for arrays of words." + StyleGuide: "https://github.com/bbatsov/ruby-style-guide#percent-w" EnforcedStyle: brackets Style/MethodCallWithArgsParentheses: - Description: 'Use parentheses for method calls with arguments.' + Description: "Use parentheses for method calls with arguments." Enabled: true - IgnoredMethods: + IgnoreMacros: - require - require_relative - raise @@ -426,37 +431,37 @@ Style/MethodCallWithArgsParentheses: # Layout Layout/ParameterAlignment: - Description: 'Here we check if the parameters on a multi-line method call or definition are aligned.' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-double-indent' + Description: "Here we check if the parameters on a multi-line method call or definition are aligned." + StyleGuide: "https://github.com/bbatsov/ruby-style-guide#no-double-indent" Enabled: false Layout/ConditionPosition: Description: >- - Checks for condition placed in a confusing position relative to - the keyword. - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#same-line-condition' + Checks for condition placed in a confusing position relative to + the keyword. + StyleGuide: "https://github.com/bbatsov/ruby-style-guide#same-line-condition" Enabled: false Layout/DotPosition: - Description: 'Checks the position of the dot in multi-line method calls.' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#consistent-multi-line-chains' + Description: "Checks the position of the dot in multi-line method calls." + StyleGuide: "https://github.com/bbatsov/ruby-style-guide#consistent-multi-line-chains" EnforcedStyle: trailing Layout/ExtraSpacing: - Description: 'Do not use unnecessary spacing.' + Description: "Do not use unnecessary spacing." Enabled: true Layout/MultilineOperationIndentation: Description: >- - Checks indentation of binary operations that span more than - one line. + Checks indentation of binary operations that span more than + one line. Enabled: true EnforcedStyle: indented Layout/MultilineMethodCallIndentation: Description: >- - Checks indentation of method calls with the dot operator - that span more than one line. + Checks indentation of method calls with the dot operator + that span more than one line. Enabled: true EnforcedStyle: indented @@ -469,20 +474,20 @@ Layout/InitialIndentation: Lint/AmbiguousOperator: Description: >- - Checks for ambiguous operators in the first argument of a - method invocation without parentheses. - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#parens-as-args' + Checks for ambiguous operators in the first argument of a + method invocation without parentheses. + StyleGuide: "https://github.com/bbatsov/ruby-style-guide#parens-as-args" Enabled: false Lint/AmbiguousRegexpLiteral: Description: >- - Checks for ambiguous regexp literals in the first argument of - a method invocation without parenthesis. + Checks for ambiguous regexp literals in the first argument of + a method invocation without parenthesis. Enabled: false Lint/AssignmentInCondition: Description: "Don't use assignment in conditions." - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#safe-assignment-in-condition' + StyleGuide: "https://github.com/bbatsov/ruby-style-guide#safe-assignment-in-condition" Enabled: false Lint/CircularArgumentReference: @@ -490,78 +495,78 @@ Lint/CircularArgumentReference: Enabled: false Lint/DeprecatedClassMethods: - Description: 'Check for deprecated class method calls.' + Description: "Check for deprecated class method calls." Enabled: false Lint/DuplicateHashKey: - Description: 'Check for duplicate keys in hash literals.' + Description: "Check for duplicate keys in hash literals." Enabled: false Lint/EachWithObjectArgument: - Description: 'Check for immutable argument given to each_with_object.' + Description: "Check for immutable argument given to each_with_object." Enabled: false Lint/ElseLayout: - Description: 'Check for odd code arrangement in an else block.' + Description: "Check for odd code arrangement in an else block." Enabled: false Lint/FormatParameterMismatch: - Description: 'The number of parameters to format/sprint must match the fields.' + Description: "The number of parameters to format/sprint must match the fields." Enabled: false Lint/SuppressedException: Description: "Don't suppress exception." - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#dont-hide-exceptions' + StyleGuide: "https://github.com/bbatsov/ruby-style-guide#dont-hide-exceptions" Enabled: false Lint/LiteralAsCondition: - Description: 'Checks of literals used in conditions.' + Description: "Checks of literals used in conditions." Enabled: false Lint/LiteralInInterpolation: - Description: 'Checks for literals used in interpolation.' + Description: "Checks for literals used in interpolation." Enabled: false Lint/Loop: Description: >- - Use Kernel#loop with break rather than begin/end/until or - begin/end/while for post-loop tests. - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#loop-with-break' + Use Kernel#loop with break rather than begin/end/until or + begin/end/while for post-loop tests. + StyleGuide: "https://github.com/bbatsov/ruby-style-guide#loop-with-break" Enabled: false Lint/NestedMethodDefinition: - Description: 'Do not use nested method definitions.' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-nested-methods' + Description: "Do not use nested method definitions." + StyleGuide: "https://github.com/bbatsov/ruby-style-guide#no-nested-methods" Enabled: false Lint/NonLocalExitFromIterator: - Description: 'Do not use return in iterator to cause non-local exit.' + Description: "Do not use return in iterator to cause non-local exit." Enabled: false Lint/ParenthesesAsGroupedExpression: Description: >- - Checks for method calls with a space before the opening - parenthesis. - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#parens-no-spaces' + Checks for method calls with a space before the opening + parenthesis. + StyleGuide: "https://github.com/bbatsov/ruby-style-guide#parens-no-spaces" Enabled: false Lint/RequireParentheses: Description: >- - Use parentheses in the method call to avoid confusion - about precedence. + Use parentheses in the method call to avoid confusion + about precedence. Enabled: false Lint/UnderscorePrefixedVariableName: - Description: 'Do not use prefix `_` for a variable that is used.' + Description: "Do not use prefix `_` for a variable that is used." Enabled: false Lint/RedundantCopDisableDirective: Description: >- - Checks for rubocop:disable comments that can be removed. - Note: this cop is not disabled when disabling all cops. - It must be explicitly disabled. + Checks for rubocop:disable comments that can be removed. + Note: this cop is not disabled when disabling all cops. + It must be explicitly disabled. Enabled: false Lint/Void: - Description: 'Possible use of operator/literal/variable in void context.' + Description: "Possible use of operator/literal/variable in void context." Enabled: false diff --git a/.slim-lint.yml b/.slim-lint.yml new file mode 100644 index 0000000..513061c --- /dev/null +++ b/.slim-lint.yml @@ -0,0 +1,9 @@ +AllCops: + NewCops: enable + TargetRubyVersion: "3.2" + +linters: + LineLength: + max: 120 + RedundantDiv: + enabled: false diff --git a/Dockerfile b/Dockerfile index 570028b..4cfcbf6 100644 --- a/Dockerfile +++ b/Dockerfile @@ -28,4 +28,4 @@ ADD . $RAILS_ROOT ENV PATH=$RAILS_ROOT/bin:${PATH} EXPOSE 3000 -CMD ["bin/prod"] +CMD ["make start"] diff --git a/Gemfile b/Gemfile index 2d6fe2a..6fceb51 100644 --- a/Gemfile +++ b/Gemfile @@ -56,6 +56,7 @@ gem 'sidekiq', '~> 7.1', '>= 7.1.1' gem 'sidekiq-cron', '~> 1.10', '>= 1.10.1' gem 'sidekiq-failures', '~> 1.0', '>= 1.0.4' +gem 'ancestry', '~> 4.3', '>= 4.3.3' gem 'pagy', '~> 6.0' gem 'ransack', '~> 4.0' gem 'responders', '~> 3.1' @@ -66,11 +67,16 @@ gem 'prawn-table', '~> 0.2.2' gem 'devise', '~> 4.2' gem 'cancancan', '~> 3.5' gem 'tzinfo' +gem 'slim', '~> 5.2', '>= 5.2.1' +gem 'slim_lint', '~> 0.27.0' +gem 'slim-rails', '~> 3.6', '>= 3.6.3' + group :development, :test do gem 'debug', platforms: [:mri, :mingw, :x64_mingw] gem 'factory_bot_rails' gem 'rubocop' + gem 'faker' end group :development do diff --git a/Gemfile.lock b/Gemfile.lock index 8ae3b86..cc1d902 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -73,6 +73,8 @@ GEM tzinfo (~> 2.0) addressable (2.8.1) public_suffix (>= 2.0.2, < 6.0) + ancestry (4.3.3) + activerecord (>= 5.2.6) ast (2.4.2) bcrypt (3.1.18) bindex (0.8.1) @@ -114,6 +116,8 @@ GEM factory_bot_rails (6.2.0) factory_bot (~> 6.2.0) railties (>= 5.0.0) + faker (3.3.0) + i18n (>= 1.8.11, < 2) fugit (1.8.1) et-orbi (~> 1, >= 1.2.7) raabro (~> 1.4) @@ -256,6 +260,16 @@ GEM simple_form (5.2.0) actionpack (>= 5.2) activemodel (>= 5.2) + slim (5.2.1) + temple (~> 0.10.0) + tilt (>= 2.1.0) + slim-rails (3.6.3) + actionpack (>= 3.1) + railties (>= 3.1) + slim (>= 3.0, < 6.0, != 5.0.0) + slim_lint (0.27.0) + rubocop (>= 1.0, < 2.0) + slim (>= 3.0, < 6.0) sprockets (4.2.0) concurrent-ruby (~> 1.0) rack (>= 2.2.4, < 4) @@ -272,7 +286,9 @@ GEM state_machines-activemodel (>= 0.8.0) stimulus-rails (1.2.1) railties (>= 6.0.0) + temple (0.10.3) thor (1.2.1) + tilt (2.3.0) timeout (0.3.1) ttfunk (1.7.0) turbo-rails (1.3.3) @@ -307,6 +323,7 @@ PLATFORMS DEPENDENCIES active_model_serializers (~> 0.10.13) + ancestry (~> 4.3, >= 4.3.3) bcrypt (~> 3.1, >= 3.1.18) bootsnap cancancan (~> 3.5) @@ -315,6 +332,7 @@ DEPENDENCIES debug devise (~> 4.2) factory_bot_rails + faker importmap-rails jbuilder jsbundling-rails @@ -333,6 +351,9 @@ DEPENDENCIES sidekiq-cron (~> 1.10, >= 1.10.1) sidekiq-failures (~> 1.0, >= 1.0.4) simple_form (~> 5.2) + slim (~> 5.2, >= 5.2.1) + slim-rails (~> 3.6, >= 3.6.3) + slim_lint (~> 0.27.0) sprockets-rails state_machines (~> 0.5.0) state_machines-activerecord (~> 0.8.0) diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..3d45e89 --- /dev/null +++ b/Makefile @@ -0,0 +1,29 @@ +setup: + bundle install + yarn install + yarn build + yarn build:css + bin/rails db:drop db:create db:migrate db:seed + +start: + bundle install + yarn install + yarn build + yarn build:css + rm ./tmp/pids/server.pid + bin/dev + +clean: + bin/rails db:drop db:create db:migrate db:seed + + +check: test lint + +lint: + bundle exec rubocop -a +# bundle exec slim-lint app/views/ + +test: + bin/rails test + +.PHONY: test diff --git a/README.md b/README.md index 167760d..ce0346c 100644 --- a/README.md +++ b/README.md @@ -9,74 +9,49 @@ for ARMStrong, OMIT and assistant for shield "D". ## Before start -### Configuring your workspace: - -#### Install and configure Docker and Docker-Compose; - -Installing: +### Local installation: ```bash -sudo dnf remove docker \ - docker-client \ - docker-client-latest \ - docker-common \ - docker-latest \ - docker-latest-logrotate \ - docker-logrotate \ - docker-selinux \ - docker-engine-selinux \ - docker-engine - -sudo dnf -y install dnf-plugins-core - -sudo dnf config-manager \ - --add-repo \ - https://download.docker.com/linux/fedora/docker-ce.repo - -sudo dnf install docker-ce docker-ce-cli containerd.io docker-compose-plugin +git clone git@github.com:digital-armstrong/Armstrong.Web.git && \ + cd ./Armstrong.Web && \ + docker compose run --rm web bash -c "make setup" ``` -Fixing problem: +This commands cloned repo and setup prroject dependency. Also you can manually install all deps: ```bash -usermod -a -G docker $USER +bundle install +yarn install +yarn build +yarn build:css +bin/rails db:drop db:create db:migrate db:seed ``` -Start after system be load: +## Start + +After installing the dependencies, you can run the project in docker compose: ```bash -sudo systemctl enable docker +docker compose up --build ``` -#### Install [ZSH and Oh-my-zsh](https://ohmyz.sh/) +That's all. =) -Install: +## Other options -```bash -sudo dnf install zsh -``` +All of the below commands must be executed inside the container. -```bash -sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)" -``` +Connect to a running container: `docker exec -it armstrongweb_web_1 bash` +Clean startup with command execution: `docker compose run --rm web bash -c ""` -Set as default shell: +### Refresh database ```bash -chsh -s $(which zsh) +make cleanup ``` -#### Install [git-flow](https://github.com/petervanderdoes/gitflow-avh) - -Install: +### Test and lint ```bash -$ wget -q https://raw.githubusercontent.com/petervanderdoes/gitflow-avh/develop/contrib/gitflow-installer.sh && sudo bash gitflow-installer.sh install stable; rm gitflow-installer.sh +make check ``` - -### Read manual - -- [Git-flow](https://jeffkreeftmeijer.com/git-flow/) -- [Git-flow usage](https://github.com/petervanderdoes/gitflow-avh#git-flow-usage) - - diff --git a/app/controllers/admin/users_controller.rb b/app/controllers/admin/users_controller.rb index c49f9f0..b554fd3 100644 --- a/app/controllers/admin/users_controller.rb +++ b/app/controllers/admin/users_controller.rb @@ -59,7 +59,12 @@ def create def destroy user = User.find(params[:id]) - assigned_inspections_count = Inspection.where(creator_id: params[:id]).or(Inspection.where(performer_id: params[:id])).count + user.posts.count + assigned_inspections_count = + Inspection. + where(creator_id: params[:id]). + or(Inspection.where(performer_id: params[:id])). + count + user.posts. + count if assigned_inspections_count.zero? @user.destroy diff --git a/app/controllers/api/v1/histories_controller.rb b/app/controllers/api/v1/histories_controller.rb index df8d719..9271b77 100644 --- a/app/controllers/api/v1/histories_controller.rb +++ b/app/controllers/api/v1/histories_controller.rb @@ -2,19 +2,48 @@ module Api class V1::HistoriesController < ApplicationController before_action :set_channel, only: [:show] + def index + datetime_interval = diff_hours(params[:start_datetime], params[:end_datetime]) + histories = if params[:start_datetime].present? && params[:end_datetime].present? && datetime_interval < 2 + History.where(event_datetime: params[:start_datetime]..params[:end_datetime]) + else + { + code: 403, + message: 'Forbidden. Parameters is not a valid or range of the datetime is too long.', + hint: 'The interval between start_datetime and end_datetime should be no more than two hours.', + }.to_json + end + + render(json: histories, except: [:id, :event_impulse_value, :event_not_system_value, :created_at, :updated_at]) + end + def show - histories = History.select { |hs| hs.channel_id == @channel_id }.last(100) + histories = if params[:start_datetime].present? && params[:end_datetime].present? + History.where(event_datetime: params[:start_datetime]..params[:end_datetime], + channel_id: @channel.id) + else + History.where(channel_id: @channel.id).last(100) + end result = histories.sort { |a, b| a[:event_datetime] <=> b[:event_datetime] } - - render(json: result) + render(json: result, except: [:created_at, :updated_at]) end private def set_channel @channel = Channel.find(params[:id]) - @channel_id = @channel.id + rescue ActiveRecord::RecordNotFound => e + render(json: { error: e }, status: :not_found) + end + + # Returns the integer value of the difference + # between the start and end datetime values + def diff_hours(start_date, end_date) + if start_date && end_date + diff_in_seconds = end_date.to_time - start_date.to_time + (diff_in_seconds / (60**2)).to_i + end end end end diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index b0cb009..b6ea9cc 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -15,13 +15,13 @@ def current_ability private - def set_time_zone(&block) + def set_time_zone(&) timezone = if current_user.nil? 'UTC' else current_user.timezone end - Time.use_zone(timezone, &block) + Time.use_zone(timezone, &) end protected diff --git a/app/controllers/concerns/organization_concern.rb b/app/controllers/concerns/organization_concern.rb index 6abbc74..99f9da0 100644 --- a/app/controllers/concerns/organization_concern.rb +++ b/app/controllers/concerns/organization_concern.rb @@ -1,6 +1,8 @@ module OrganizationConcern extend ActiveSupport::Concern + # rubocop:disable Metrics/BlockLength + included do def organization_index @query = Organization.ransack(params[:q]) @@ -57,4 +59,6 @@ def organization_params ) end end + + # rubocop:enable Metrics/BlockLength end diff --git a/app/controllers/inspection_controller.rb b/app/controllers/inspection_controller.rb index 86f6300..4d88120 100644 --- a/app/controllers/inspection_controller.rb +++ b/app/controllers/inspection_controller.rb @@ -16,12 +16,12 @@ def tasks(condition, method_name) @query = Inspection.ransack(params[:q]) @query.sorts = ['updated_at desc'] @previous_action = method_name - if method_name != :service_tasks - @pagy, @inspections = pagy(@query.result.where(condition). - includes(:device, :creator, :performer)) - else + if method_name == :service_tasks @pagy, @inspections = pagy(@query.result.joins(:device).where(condition). includes(:device, :creator, :performer)) + else + @pagy, @inspections = pagy(@query.result.where(condition). + includes(:device, :creator, :performer)) end end diff --git a/app/controllers/posts/application_controller.rb b/app/controllers/posts/application_controller.rb new file mode 100644 index 0000000..1bf1408 --- /dev/null +++ b/app/controllers/posts/application_controller.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: true + +module Posts + class ApplicationController < ApplicationController + def resource_post + @resource_post ||= Post.find(params[:post_id]) + end + end +end diff --git a/app/controllers/posts/comments_controller.rb b/app/controllers/posts/comments_controller.rb new file mode 100644 index 0000000..3baa8d6 --- /dev/null +++ b/app/controllers/posts/comments_controller.rb @@ -0,0 +1,24 @@ +# frozen_string_literal: true + +module Posts + class CommentsController < ApplicationController + before_action :authenticate_user!, only: [:create] + + def create + @comment = resource_post.comments.build(comments_params) + @comment.user = current_user + + if @comment.save + redirect_to(resource_post, notice: t('.success')) + else + redirect_to(resource_post, alert: @comment.errors.full_messages.join('. ')) + end + end + + private + + def comments_params + params.require(:post_comment).permit(:content, :parent_id) + end + end +end diff --git a/app/controllers/posts/likes_controller.rb b/app/controllers/posts/likes_controller.rb new file mode 100644 index 0000000..3f65abe --- /dev/null +++ b/app/controllers/posts/likes_controller.rb @@ -0,0 +1,24 @@ +# frozen_string_literal: true + +module Posts + class LikesController < ApplicationController + before_action :authenticate_user! + before_action :set_like, only: [:destroy] + + def create + resource_post.likes.find_or_create_by(user: current_user) + redirect_to(resource_post) + end + + def destroy + @like&.destroy + redirect_to(resource_post) + end + + private + + def set_like + @like = resource_post.likes.find_by(user: current_user) + end + end +end diff --git a/app/controllers/post_controller.rb b/app/controllers/posts_controller.rb similarity index 69% rename from app/controllers/post_controller.rb rename to app/controllers/posts_controller.rb index 16d1abf..7140242 100644 --- a/app/controllers/post_controller.rb +++ b/app/controllers/posts_controller.rb @@ -1,12 +1,17 @@ -class PostController < ApplicationController +class PostsController < ApplicationController before_action :authenticate_user! before_action :set_post, only: [:show, :edit, :update, :destroy] load_and_authorize_resource def index - @query = Post.ransack(params[:q]) - @query.sorts = ['updated_at desc'] - @pagy, @posts = pagy(@query.result) + @pagy, @posts = pagy(Post.includes(:user).all) + end + + def show + @post = Post.find(params[:id]) + @post_comments = @post.comments.includes(:user) + @user_likes = @post.likes.find_by(user_id: current_user.id) if current_user + @comment = PostComment.new end def new @@ -23,7 +28,7 @@ def create if @post.save redirect_to(post_path(@post.id)) else - render(:new) + render(:new, status: :unprocessable_entity) end end @@ -37,7 +42,7 @@ def update def destroy @post.destroy - redirect_to(home_index_path) + redirect_to(root_path) end private diff --git a/app/controllers/users/registrations_controller.rb b/app/controllers/users/registrations_controller.rb index 608f5f0..bb652a4 100644 --- a/app/controllers/users/registrations_controller.rb +++ b/app/controllers/users/registrations_controller.rb @@ -4,6 +4,8 @@ class Users::RegistrationsController < Devise::RegistrationsController before_action :configure_sign_up_params, only: [:create] before_action :configure_account_update_params, only: [:update] + # rubocop:disable Lint/UselessMethodDefinition + # GET /resource/sign_up def new super @@ -59,4 +61,6 @@ def destroy # def after_inactive_sign_up_path_for(resource) # super(resource) # end + + # rubocop:enable Lint/UselessMethodDefinition end diff --git a/app/controllers/users/sessions_controller.rb b/app/controllers/users/sessions_controller.rb index 8a5fc3d..cd3cc69 100644 --- a/app/controllers/users/sessions_controller.rb +++ b/app/controllers/users/sessions_controller.rb @@ -3,6 +3,9 @@ class Users::SessionsController < Devise::SessionsController # before_action :configure_sign_in_params, only: [:create] skip_before_action :verify_authenticity_token, only: [:create] + + # rubocop:disable Lint/UselessMethodDefinition + # GET /resource/sign_in def new super @@ -28,4 +31,6 @@ def destroy def configure_sign_in_params devise_parameter_sanitizer.permit(:sign_in, keys: [:attribute]) end + + # rubocop:enable Lint/UselessMethodDefinition end diff --git a/app/helpers/posts/comments_helper.rb b/app/helpers/posts/comments_helper.rb new file mode 100644 index 0000000..7775235 --- /dev/null +++ b/app/helpers/posts/comments_helper.rb @@ -0,0 +1,2 @@ +module Posts::CommentsHelper +end diff --git a/app/helpers/posts/likes_helper.rb b/app/helpers/posts/likes_helper.rb new file mode 100644 index 0000000..6e294d2 --- /dev/null +++ b/app/helpers/posts/likes_helper.rb @@ -0,0 +1,2 @@ +module Posts::LikesHelper +end diff --git a/app/middlewares/rate_limiter.rb b/app/middlewares/rate_limiter.rb new file mode 100644 index 0000000..d0bf812 --- /dev/null +++ b/app/middlewares/rate_limiter.rb @@ -0,0 +1,33 @@ +class RateLimiter + RATE_LIMIT = 10.seconds + RATE_LIMIT_MESSAGE = { code: 429, message: 'Too many requests. Please try again later.' }.to_json + + def initialize(app) + @app = app + @request_counts = {} + end + + def call(env) + request = Rack::Request.new(env) + + if request.path.start_with?('/api') + ip_address = request.ip + + @request_counts[ip_address] ||= { count: 0, last_request_at: nil } + + if @request_counts[ip_address][:last_request_at] && + @request_counts[ip_address][:last_request_at] > Time.now - RATE_LIMIT + @request_counts[ip_address][:count] += 1 + else + @request_counts[ip_address][:count] = 1 + @request_counts[ip_address][:last_request_at] = Time.now + end + + if @request_counts[ip_address][:count] > 1 + return [429, { 'Content-Type' => 'application/json' }, [RATE_LIMIT_MESSAGE]] + end + end + + @app.call(env) + end +end diff --git a/app/middlewares/set_locale_middleware.rb b/app/middlewares/set_locale_middleware.rb new file mode 100644 index 0000000..97b55eb --- /dev/null +++ b/app/middlewares/set_locale_middleware.rb @@ -0,0 +1,26 @@ +# frozen_string_literal: true + +class SetLocaleMiddleware + def initialize(app) + @app = app + end + + # BEGIN + def call(env) + request = Rack::Request.new(env) + + locale = extract_locale(request) || I18n.default_locale + I18n.locale = locale.downcase.to_sym + + status, headers, response = @app.call(env) + headers['Content-Language'] = locale + + [status, headers, response] + end + + def extract_locale(request) + locale = request.env['HTTP_ACCEPT_LANGUAGE']&.scan(/^[a-z]{2}/)&.first + + I18n.available_locales.map(&:to_s).include?(locale) ? locale : nil + end +end diff --git a/app/models/channel.rb b/app/models/channel.rb index 54477c8..06fff9f 100644 --- a/app/models/channel.rb +++ b/app/models/channel.rb @@ -14,7 +14,15 @@ def self.ransackable_associations(_auth_object = nil) end def self.ransackable_attributes(_auth_object = nil) - ['channel_id', 'consumption', 'control_point_id', 'conversion_coefficient', 'created_at', 'emergency_limit', 'event_count', - 'event_datetime', 'event_error_count', 'event_impulse_value', 'event_not_system_value', 'event_system_value', 'id', 'is_online', 'is_special_control', 'location_description', 'pre_emergency_limit', 'self_background', 'server_id', 'service_id', 'state', 'updated_at'] + [ + 'channel_id', 'consumption', 'control_point_id', + 'conversion_coefficient', 'created_at', + 'emergency_limit', 'event_count', 'event_datetime', + 'event_error_count', 'event_impulse_value', 'event_not_system_value', + 'event_system_value', 'id', 'is_online', + 'is_special_control', 'location_description', 'pre_emergency_limit', + 'self_background', 'server_id', 'service_id', + 'state', 'updated_at' + ] end end diff --git a/app/models/concerns/export_pdf.rb b/app/models/concerns/export_pdf.rb index d062225..d7d3d28 100644 --- a/app/models/concerns/export_pdf.rb +++ b/app/models/concerns/export_pdf.rb @@ -5,8 +5,8 @@ module ExportPdf module ClassMethods def to_pdf - require 'prawn' - require 'prawn/table' + require('prawn') + require('prawn/table') options = { position: :center, column_widths: [100, 100, 200, 100, 100], width: 600 } diff --git a/app/models/device.rb b/app/models/device.rb index cf19910..e056e9f 100644 --- a/app/models/device.rb +++ b/app/models/device.rb @@ -5,7 +5,6 @@ class Device < ApplicationRecord current_year = Date.today.year year_error_msg = "должен быть больше 1900 и меньше или равен #{current_year}" - inspection_interval_msg = 'должен быть от 0.1 (раз в месяц) до 10.0 (раз в 10 лет)' belongs_to :device_model belongs_to :device_reg_group diff --git a/app/models/post.rb b/app/models/post.rb index 87e190e..0b9a20f 100644 --- a/app/models/post.rb +++ b/app/models/post.rb @@ -1,7 +1,14 @@ class Post < ApplicationRecord belongs_to :user + has_many :comments, class_name: 'PostComment', dependent: :destroy + has_many :likes, class_name: 'PostLike', dependent: :destroy + validates :user, presence: true + validates :title, presence: true, length: { minimum: 5, maximum: 255 } + validates :body, presence: true, length: { minimum: 200, maximum: 4000 } + + scope :latest, -> { order(created_at: :desc) } def formatted_date(param) I18n.l(param, format: :long) diff --git a/app/models/post_comment.rb b/app/models/post_comment.rb new file mode 100644 index 0000000..72ae0ed --- /dev/null +++ b/app/models/post_comment.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +class PostComment < ApplicationRecord + belongs_to :post, counter_cache: :comments_count + belongs_to :user + + has_ancestry + + validates :content, presence: true +end diff --git a/app/models/post_like.rb b/app/models/post_like.rb new file mode 100644 index 0000000..ec7bea6 --- /dev/null +++ b/app/models/post_like.rb @@ -0,0 +1,4 @@ +class PostLike < ApplicationRecord + belongs_to :user + belongs_to :post, counter_cache: :likes_count +end diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb index 25a82b3..0402870 100644 --- a/app/views/layouts/application.html.erb +++ b/app/views/layouts/application.html.erb @@ -26,15 +26,15 @@ -
-
+
+