<commit_before>module Her
  module Model
    class Relation
      attr_accessor :query_attrs

      # @private
      def initialize(parent)
        @parent = parent
        @query_attrs = {}
      end

      # Build a new resource
      def build(attrs = {})
        @parent.new(@query_attrs.merge(attrs))
      end

      # Add a query string parameter
      def where(attrs = {})
        return self if attrs.blank?
        self.clone.tap { |a| a.query_attrs = a.query_attrs.merge(attrs) }
      end
      alias :all :where

      # Bubble all methods to the fetched collection
      def method_missing(method, *args, &blk)
        fetch.send(method, *args, &blk)
      end

      # @private
      def nil?
        fetch.nil?
      end

      # @private
      def kind_of?(thing)
        fetch.kind_of?(thing)
      end

      # Fetch a collection of resources
      #
      # @example
      #   @users = User.all
      #   # Fetched via GET "/users"
      #
      # @example
      #   @users = User.where(:approved => 1).all
      #   # Fetched via GET "/users?approved=1"
      def fetch
        @_fetch ||= begin
          path = @parent.build_request_path(@query_attrs)
          @parent.request(@query_attrs.merge(:_method => :get, :_path => path)) do |parsed_data, response|
            @parent.new_collection(parsed_data)
          end
        end
      end

      # Create a resource and return it
      #
      # @example
      #   @user = User.create(:fullname => "<NAME>")
      #   # Called via POST "/users/1" with `&fullname=Tobias+Fünke`
      #
      # @example
      #   @user = User.where(:email => "<EMAIL>").create(:fullname => "<NAME>")
      #   # Called via POST "/users/1" with `&email=<EMAIL>&fullname=Tobias+Fünke`
      def create(params={})
        resource = @parent.new(@query_attrs.merge(params))
        resource.save

        resource
      end
    end
  end
end<commit_msg>Add first_or_create and first_or_initialize<commit_after>module Her
  module Model
    class Relation
      attr_accessor :query_attrs

      # @private
      def initialize(parent)
        @parent = parent
        @query_attrs = {}
      end

      # Build a new resource
      def build(attrs = {})
        @parent.new(@query_attrs.merge(attrs))
      end

      # Add a query string parameter
      def where(attrs = {})
        return self if attrs.blank?
        self.clone.tap { |a| a.query_attrs = a.query_attrs.merge(attrs) }
      end
      alias :all :where

      # Bubble all methods to the fetched collection
      def method_missing(method, *args, &blk)
        fetch.send(method, *args, &blk)
      end

      # @private
      def nil?
        fetch.nil?
      end

      # @private
      def kind_of?(thing)
        fetch.kind_of?(thing)
      end

      # Fetch a collection of resources
      #
      # @example
      #   @users = User.all
      #   # Fetched via GET "/users"
      #
      # @example
      #   @users = User.where(:approved => 1).all
      #   # Fetched via GET "/users?approved=1"
      def fetch
        @_fetch ||= begin
          path = @parent.build_request_path(@query_attrs)
          @parent.request(@query_attrs.merge(:_method => :get, :_path => path)) do |parsed_data, response|
            @parent.new_collection(parsed_data)
          end
        end
      end

      # Create a resource and return it
      #
      # @example
      #   @user = User.create(:fullname => "<NAME>")
      #   # Called via POST "/users/1" with `&fullname=Tobias+Fünke`
      #
      # @example
      #   @user = User.where(:email => "<EMAIL>").create(:fullname => "<NAME>")
      #   # Called via POST "/users/1" with `&email=<EMAIL>&fullname=Tobias+Fünke`
      def create(attrs = {})
        resource = @parent.new(@query_attrs.merge(attrs))
        resource.save

        resource
      end

      # Fetch a resource and create it if it's not found
      #
      # @example
      #   @user = User.where(:email => "<EMAIL>").find_or_create
      #
      #   # Returns the first item of the collection if present:
      #   # GET "/users?email=<EMAIL>"
      #
      #   # If collection is empty:
      #   # POST /users with `email=<EMAIL>`
      def first_or_create(attrs = {})
        fetch.first || create(attrs)
      end

      # Fetch a resource and build it if it's not found
      #
      # @example
      #   @user = User.where(:email => "<EMAIL>").find_or_initialize
      #
      #   # Returns the first item of the collection if present:
      #   # GET "/users?email=<EMAIL>"
      #
      #   # If collection is empty:
      #   @user.email # => "<EMAIL>"
      #   @user.new? # => true
      def first_or_initialize(attrs = {})
        fetch.first || build(attrs)
      end
    end
  end
end
{'fraction_non_alphanumeric': 0.12075869336143309, 'fraction_numerical': 0.0016859852476290833, 'mean_word_length': 1.899205864386072, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 33, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7454724', 'n_tokens_mistral': 1490, 'n_tokens_neox': 1470, 'n_words': 360}