CINXE.COM

Patterns - RubyGems Guides

<!DOCTYPE html> <html lang="en-us"> <head> <title>Patterns - RubyGems Guides</title> <meta charset="utf-8" /> <link rel="icon" href="/favicon.ico" type="image/x-icon"> <link rel="icon" href="/favicon.icns"> <meta http-equiv="Description" name="Description" content="Tutorials, guides, FAQs for RubyGems package management" /> <meta http-equiv="Keywords" name="Keywords" content="rubygems, gems, programming, ruby, packages" /> <meta content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0" name="viewport"> <link href="/stylesheets/application.css" rel="stylesheet" type="text/css" /> <script src="//code.jquery.com/jquery-3.6.0.min.js"></script> <script src="/javascripts/mobile-nav.js" type="text/javascript"></script> <script src="//use.typekit.net/omu5dik.js" type="text/javascript"></script> <script> try{Typekit.load();}catch(e){} </script> <script> $(function() { var path = window.location.pathname; $('a.nav--v__link[href="'+path.substring(0, path.length -1)+'"]').addClass('is-active'); var header_link = $('a.header__nav-link[href="'+path.substring(0, path.length -1)+'"]'); if(header_link.length > 0) { $('.header__nav-links a').removeClass('is-active'); header_link.addClass('is-active'); } }); </script> <!--[if !IE]>--> <meta name="viewport" content="width=device-width"> <script type="text/javascript"> window.scrollTo(0, 1); </script> <!--<![endif]--> <!--[if lt IE 9]> <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script> <![endif]--> </head> <body class="default"> <header class="header header--interior"> <div class="l-wrap--header"> <a class="header__logo-wrap" href="https://rubygems.org/"> <span class="header__logo" data-icon="⬡">⬢</span> <span class="t-hidden">RubyGems</span> </a> <a class="header__club-sandwich" href="#"> <span class="t-hidden">Navigation menu</span> </a> <div class="header__nav-links-wrap"> <form accept-charset="UTF-8" action="https://rubygems.org/search" class="header__search-wrap" id="main-search" method="get"> <input class="header__search" id="query" name="query" placeholder="Search Gems&hellip;" type="search" /> <label for="query"> <span class="t-hidden">Search gems</span> </label> <input class="header__search__icon" id="search_submit" type="submit" value="⌕" /> </form> <nav class="header__nav-links"> <a class="header__nav-link" href="https://rubygems.org/releases">Releases</a> <a class="header__nav-link" href="https://blog.rubygems.org">Blog</a> <a class="header__nav-link" href="https://rubygems.org/gems">Gems</a> <a class="header__nav-link is-active" href="/">Guides</a> <a class="header__nav-link" href="/contributing">Contribute</a> </nav> </div> </div> </header> <main class="main--interior"> <div class="l-wrap--b"> <a class="t-display page__heading" href="/">Guides</a> <div class="l-overflow"> <div class="l-col--l"> <ul class="nav--v"> <li><a class="nav--v__link" href="/rubygems-basics">RubyGems Basics</a></li> <li><a class="nav--v__link" href="/what-is-a-gem">What is a gem?</a></li> <li><a class="nav--v__link" href="/make-your-own-gem">Make your own gem</a></li> <li><a class="nav--v__link" href="/gems-with-extensions">Gems with Extensions</a></li> <li><a class="nav--v__link" href="/name-your-gem">Name your gem</a></li> <li><a class="nav--v__link" href="/publishing">Publishing your gem</a></li> <li><a class="nav--v__link" href="/security">Security Practices</a></li> <li><a class="nav--v__link" href="/managing-owners-using-ui">Managing owners using UI</a></li> <li><a class="nav--v__link" href="/removing-a-published-gem">Removing a Published gem</a></li> <li><a class="nav--v__link" href="/ssl-certificate-update">SSL Certificate Update</a></li> <li><a class="nav--v__link" href="/patterns">Patterns</a></li> <li><a class="nav--v__link" href="/specification-reference">Specification Reference</a></li> <li><a class="nav--v__link" href="/command-reference">Command Reference</a></li> <li><a class="nav--v__link" href="/rubygems-org-api">RubyGems.org API</a></li> <li><a class="nav--v__link" href="/rubygems-org-api-v2">RubyGems.org API V2.0</a></li> <li><a class="nav--v__link" href="/rubygems-org-compact-index-api">RubyGems.org Compact Index API</a></li> <li><a class="nav--v__link" href="/rubygems-org-rate-limits">RubyGems.org rate limits</a></li> <li><a class="nav--v__link" href="/api-key-scopes">API key scopes</a></li> <li><a class="nav--v__link" href="/run-your-own-gem-server">Run your own gem server</a></li> <li><a class="nav--v__link" href="/setting-up-multifactor-authentication">Setting up multi-factor authentication</a></li> <ul class="nav--v"> <li><a class="nav--v__link" href="/setting-up-webauthn-mfa">Setting up WebAuthn MFA</a></li> <li><a class="nav--v__link" href="/setting-up-otp-mfa">Setting up OTP MFA</a></li> </ul> <li><a class="nav--v__link" href="/using-mfa-in-command-line">Using multi-factor authentication in command line</a></li> <ul class="nav--v"> <li><a class="nav--v__link" href="/using-webauthn-mfa-in-command-line">Using WebAuthn for MFA</a></li> <li><a class="nav--v__link" href="/using-otp-mfa-in-command-line">Using OTP for MFA</a></li> </ul> <li><a class="nav--v__link" href="/mfa-requirement-opt-in">MFA requirement opt in</a></li> <li><a class="nav--v__link" href="/using-s3-source">Using S3 as gem source</a></li> <li><a class="nav--v__link" href="/resources">Resources</a></li> <li><a class="nav--v__link" href="/contributing">Contributing to RubyGems</a></li> <li><a class="nav--v__link" href="/faqs">Frequently Asked Questions</a></li> <li><a class="nav--v__link" href="/plugins">Plugins</a></li> <li><a class="nav--v__link" href="/cve">Common Vulnerabilities and Exposures</a></li> <li><a class="nav--v__link" href="/releasing-rubygems">Releasing RubyGems</a></li> <li><a class="nav--v__link" href="/trusted-publishing">Trusted Publishing</a></li> <ul class="nav--v"> <li><a class="nav--v__link" href="/trusted-publishing/adding-a-publisher">Adding to an existing gem</a></li> <li><a class="nav--v__link" href="/trusted-publishing/pushing-a-new-gem">Pushing a new gem</a></li> <li><a class="nav--v__link" href="/trusted-publishing/releasing-gems">Releasing gems</a></li> </ul> <li><a class="nav--v__link" href="/credits">Credits</a></li> </ul> </div> <div class="l-colspan--r"> <div class="t-body"> <p><em class="t-gray">Common practices to make your gem users’ and other developers’ lives easier.</em></p> <ul> <li><a href="#consistent-naming">Consistent naming</a></li> <li><a href="#semantic-versioning">Semantic versioning</a></li> <li><a href="#declaring-dependencies">Declaring dependencies</a></li> <li><a href="#loading-code">Loading code</a></li> <li><a href="#prerelease-gems">Prerelease gems</a></li> </ul> <h2 id="consistent-naming">Consistent naming</h2> <blockquote> <p>There are only two hard things in Computer Science: cache invalidation and naming things. -<a href="https://martinfowler.com/bliki/TwoHardThings.html">Phil Karlton</a></p> </blockquote> <h3 id="file-names">File names</h3> <p>Be consistent with how your gem files in <code class="language-plaintext highlighter-rouge">lib</code> and <code class="language-plaintext highlighter-rouge">bin</code> are named. The <a href="https://github.com/qrush/hola">hola</a> gem from the <a href="/make-your-own-gem">make your own gem</a> guide is a great example:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>% tree . ├── Rakefile ├── bin │ └── hola ├── hola.gemspec ├── lib │ ├── hola │ │ └── translator.rb │ └── hola.rb └── test └── test_hola.rb </code></pre></div></div> <p>The executable and the primary file in <code class="language-plaintext highlighter-rouge">lib</code> are named the same. A developer can easily jump in and call <code class="language-plaintext highlighter-rouge">require 'hola'</code> with no problems.</p> <h3 id="naming-your-gem">Naming your gem</h3> <p>Naming your gem is important. Before you pick a name for your gem, do a quick search on <a href="https://rubygems.org">RubyGems.org</a> and <a href="https://github.com/search">GitHub</a> to see if someone else has taken it. Every published gem must have a unique name. Be sure to read our <a href="/name-your-gem">naming recommendations</a> when you’ve found a name you like.</p> <h2 id="semantic-versioning">Semantic versioning</h2> <p>A versioning policy is merely a set of simple rules governing how version numbers are allocated. It can be very simple (e.g. the version number is a single number starting with 1 and incremented for each successive version), or it can be really strange (Knuth’s TeX project had version numbers: 3, 3.1, 3.14, 3.141, 3.1415; each successive version added another digit to PI).</p> <p>The RubyGems team urges gem developers to follow the <a href="https://semver.org">Semantic Versioning</a> standard for their gem’s versions. The RubyGems library itself does not enforce a strict versioning policy, but using an “irrational” policy will only be a disservice to those in the community who use your gems.</p> <p>Suppose you have a ‘stack’ gem that holds a <code class="language-plaintext highlighter-rouge">Stack</code> class with both <code class="language-plaintext highlighter-rouge">push</code> and <code class="language-plaintext highlighter-rouge">pop</code> functionality. Your <code class="language-plaintext highlighter-rouge">CHANGELOG</code> might look like this if you use semantic versioning:</p> <ul> <li><strong>Version 0.1.0</strong>: The initial <code class="language-plaintext highlighter-rouge">Stack</code> class is released.</li> <li><strong>Version 0.2.0</strong>: Switched to a linked list implementation because it is cooler.</li> <li><strong>Version 0.3.0</strong>: Added a <code class="language-plaintext highlighter-rouge">depth</code> method.</li> <li><strong>Version 1.0.0</strong>: Added <code class="language-plaintext highlighter-rouge">top</code> and made <code class="language-plaintext highlighter-rouge">pop</code> return <code class="language-plaintext highlighter-rouge">nil</code> (<code class="language-plaintext highlighter-rouge">pop</code> used to return the old top item).</li> <li><strong>Version 1.1.0</strong>: <code class="language-plaintext highlighter-rouge">push</code> now returns the value pushed (it used to return <code class="language-plaintext highlighter-rouge">nil</code>).</li> <li><strong>Version 1.1.1</strong>: Fixed a bug in the linked list implementation.</li> <li><strong>Version 1.1.2</strong>: Fixed a bug introduced in the last fix.</li> </ul> <p>Semantic versioning boils down to:</p> <ul> <li><strong>PATCH</strong> <code class="language-plaintext highlighter-rouge">0.0.x</code> level changes for implementation level detail changes, such as small bug fixes</li> <li><strong>MINOR</strong> <code class="language-plaintext highlighter-rouge">0.x.0</code> level changes for any backwards compatible API changes, such as new functionality/features</li> <li><strong>MAJOR</strong> <code class="language-plaintext highlighter-rouge">x.0.0</code> level changes for backwards <em>incompatible</em> API changes, such as changes that will break existing users code if they update</li> </ul> <h2 id="declaring-dependencies">Declaring dependencies</h2> <p>Gems work with other gems. Here are some tips to make sure they’re nice to each other.</p> <h3 id="runtime-vs-development">Runtime vs. development</h3> <p>RubyGems provides two main “types” of dependencies: runtime and development. Runtime dependencies are what your gem needs to work (such as <a href="https://rubygems.org/gems/rails">rails</a> needing <a href="https://rubygems.org/gems/activesupport">activesupport</a>).</p> <p>Development dependencies are useful for when someone wants to make modifications to your gem. When you specify development dependencies, another developer can run <code class="language-plaintext highlighter-rouge">gem install --dev your_gem</code> and RubyGems will grab both sets of dependencies (runtime and development). Typical development dependencies include test frameworks and build systems.</p> <p>Setting dependencies in your gemspec is easy. Just use <code class="language-plaintext highlighter-rouge">add_runtime_dependency</code> and <code class="language-plaintext highlighter-rouge">add_development_dependency</code>:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Gem::Specification.new do |s| s.name = "hola" s.version = "2.0.0" s.add_runtime_dependency "daemons", ["= 1.1.0"] s.add_development_dependency "bourne", ["&gt;= 0"] </code></pre></div></div> <h3 id="dont-use-gem-from-within-your-gem">Don’t use <code class="language-plaintext highlighter-rouge">gem</code> from within your gem</h3> <p>You may have seen some code like this around to make sure you’re using a specific version of a gem:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>gem "extlib", "&gt;= 1.0.8" require "extlib" </code></pre></div></div> <p>It’s reasonable for applications that consume gems to use this (though they could also use a tool like <a href="https://bundler.io/">Bundler</a>). Gems themselves <strong>should not</strong> do this. They should instead use dependencies in the gemspec so RubyGems can handle loading the dependency instead of the user.</p> <h3 id="pessimistic-version-constraint">Pessimistic version constraint</h3> <p>If your gem properly follows <a href="https://semver.org">semantic versioning</a> with its versioning scheme, then other Ruby developers can take advantage of this when choosing a version constraint to lock down your gem in their application.</p> <p>Let’s say the following releases of a gem exist:</p> <ul> <li><strong>Version 2.1.0</strong> — Baseline</li> <li><strong>Version 2.2.0</strong> — Introduced some new (backward compatible) features.</li> <li><strong>Version 2.2.1</strong> — Removed some bugs</li> <li><strong>Version 2.2.2</strong> — Streamlined your code</li> <li><strong>Version 2.3.0</strong> — More new features (but still backwards compatible).</li> <li><strong>Version 3.0.0</strong> — Reworked the interface. Code written to version 2.x might not work.</li> </ul> <p>You want to use a gem, and you’ve determined that version 2.2.0 works with your software, but version 2.1.0 doesn’t have a feature you need. Adding a dependency in your gem (or a <code class="language-plaintext highlighter-rouge">Gemfile</code> from Bundler) might look like:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code># gemspec spec.add_runtime_dependency 'library', '&gt;= 2.2.0' # bundler gem 'library', '&gt;= 2.2.0' </code></pre></div></div> <p>This is an “optimistic” version constraint. It’s saying that all versions greater than or equal to 2.2.0 will work with your software.</p> <p>However, you might know that 3.0 introduces a breaking change and is no longer compatible. The way to designate this is to be “pessimistic”. This explicitly excludes the versions that might break your code:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code># gemspec spec.add_runtime_dependency 'library', ['&gt;= 2.2.0', '&lt; 3.0'] # bundler gem 'library', '&gt;= 2.2.0', '&lt; 3.0' </code></pre></div></div> <p>RubyGems provides a shortcut for this, commonly known as the <a href="https://robots.thoughtbot.com/post/2508037841/twiddle-wakka">twiddle-wakka</a>:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code># gemspec spec.add_runtime_dependency 'library', '~&gt; 2.2' # bundler gem 'library', '~&gt; 2.2' </code></pre></div></div> <p>Notice that we dropped the <code class="language-plaintext highlighter-rouge">PATCH</code> level of the version number. Had we said <code class="language-plaintext highlighter-rouge">~&gt; 2.2.0</code>, that would have been equivalent to <code class="language-plaintext highlighter-rouge">['&gt;= 2.2.0', '&lt; 2.3.0']</code>.</p> <p>If you want to allow use of newer backwards-compatible versions but need a specific bug fix you can use a compound requirement:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code># gemspec spec.add_runtime_dependency 'library', '~&gt; 2.2', '&gt;= 2.2.1' # bundler gem 'library', '~&gt; 2.2', '&gt;= 2.2.1' </code></pre></div></div> <p>The important note to take home here is to be aware others <em>will</em> be using your gems, so guard yourself from potential bugs/failures in future releases by using <code class="language-plaintext highlighter-rouge">~&gt;</code> instead of <code class="language-plaintext highlighter-rouge">&gt;=</code> if at all possible.</p> <blockquote> <p>If you’re dealing with a lot of gem dependencies in your application, we recommend that you take a look into <a href="https://bundler.io/">Bundler</a> or <a href="https://github.com/jbarnette/isolate">Isolate</a> which do a great job of managing a complex version manifest for many gems.</p> </blockquote> <p>It’s also important to know that if you specify a major version only, like this:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code># gemspec spec.add_runtime_dependency 'library', '~&gt; 2' </code></pre></div></div> <p>It will only use the latest version from the 2.x series – so 2.3.0 – and not 3.0.0. This behaviour may surprise some people, but automatically allowing any major version past version 2 is more surprising behaviour.</p> <p>You can also exclude specific versions using <code class="language-plaintext highlighter-rouge">!=</code>. Let’s say version 2.2.1 has a show-stopping bug, or a change that accidentally breaks backwards-compatibility, and thus breaks your gem. You can exclude it as follows:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code># gemspec spec.add_runtime_dependency 'library', '~&gt; 2', '!= 2.2.1' </code></pre></div></div> <p>You can append additional versions by adding them as an additional argument to <code class="language-plaintext highlighter-rouge">add_runtime_dependency</code> - after all, its last argument is just an array.</p> <h3 id="prerelease-dependency">Prerelease dependency</h3> <p>When using stable requirements, Bundler will “prefer” using stable gems, only using prerelease gems if necessary.</p> <p>However, if you want to use prerelease gems, then you can declare a prerelease requirement using non-numerical characters:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code># gemspec spec.add_runtime_dependency 'library', '&gt;= 2.0.0.a', '&lt; 2.0.0' </code></pre></div></div> <p>When a prerelease requirement is given, Bundler will respect the actual semantic versioning precedence for that gem.</p> <h3 id="requiring-rubygems">Requiring RubyGems</h3> <p>Summary: don’t.</p> <p>This line…</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>require 'rubygems' </code></pre></div></div> <p>…should not be necessary in your gem code, since RubyGems is loaded already when a gem is required. Not having <code class="language-plaintext highlighter-rouge">require 'rubygems'</code> in your code means that the gem can be easily used without needing the RubyGems client to run.</p> <p>For more information please check out <a href="https://tomayko.com/writings/require-rubygems-antipattern">Ryan Tomayko’s</a> original post about the subject.</p> <h2 id="loading-code">Loading code</h2> <p>At its core, RubyGems exists to help you manage Ruby’s <code class="language-plaintext highlighter-rouge">$LOAD_PATH</code>, which is how the <code class="language-plaintext highlighter-rouge">require</code> statement picks up new code. There’s several things you can do to make sure you’re loading code the right way.</p> <h3 id="respect-the-global-load-path">Respect the global load path</h3> <p>When packaging your gem files, you need to be careful of what is in your <code class="language-plaintext highlighter-rouge">lib</code> directory. Every gem you have installed gets its <code class="language-plaintext highlighter-rouge">lib</code> directory appended onto your <code class="language-plaintext highlighter-rouge">$LOAD_PATH</code>. This means any file on the top level of the <code class="language-plaintext highlighter-rouge">lib</code> directory could get required.</p> <p>For example, let’s say we have a <code class="language-plaintext highlighter-rouge">foo</code> gem with the following structure:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>. └── lib ├── foo │ └── cgi.rb ├── erb.rb ├── foo.rb └── set.rb </code></pre></div></div> <p>This might seem harmless since your custom <code class="language-plaintext highlighter-rouge">erb</code> and <code class="language-plaintext highlighter-rouge">set</code> files are within your gem. However, this is not harmless, anyone who requires this gem will not be able to bring in the <a href="https://docs.ruby-lang.org/en/master/ERB.html">ERB</a> or <a href="https://docs.ruby-lang.org/en/master/Set.html">Set</a> classes provided by Ruby’s standard library.</p> <p>The best way to get around this is to keep files in a different directory under <code class="language-plaintext highlighter-rouge">lib</code>. The usual convention is to be consistent and put them in the same folder name as your gem’s name, for example <code class="language-plaintext highlighter-rouge">lib/foo/cgi.rb</code>.</p> <h3 id="requiring-files-relative-to-each-other">Requiring files relative to each other</h3> <p>Gems should not have to use <code class="language-plaintext highlighter-rouge">__FILE__</code> to bring in other Ruby files in your gem. Code like this is surprisingly common in gems:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>require File.join( File.dirname(__FILE__), "foo", "bar") </code></pre></div></div> <p>Or:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>require File.expand_path(File.join( File.dirname(__FILE__), "foo", "bar")) </code></pre></div></div> <p>The fix is simple, just require the file relative to the load path:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>require 'foo/bar' </code></pre></div></div> <p>Or use require_relative:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>require_relative 'foo/bar' </code></pre></div></div> <p>The <a href="/make-your-own-gem">make your own gem</a> guide has a great example of this behavior in practice, including a working test suite. The code for that gem is <a href="https://github.com/qrush/hola">on GitHub</a> as well.</p> <h3 id="mangling-the-load-path">Mangling the load path</h3> <p>Gems should not change the <code class="language-plaintext highlighter-rouge">$LOAD_PATH</code> variable. RubyGems manages this for you. Code like this should not be necessary:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>lp = File.expand_path(File.dirname(__FILE__)) unless $LOAD_PATH.include?(lp) $LOAD_PATH.unshift(lp) end </code></pre></div></div> <p>Or:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>__DIR__ = File.dirname(__FILE__) $LOAD_PATH.unshift __DIR__ unless $LOAD_PATH.include?(__DIR__) || $LOAD_PATH.include?(File.expand_path(__DIR__)) </code></pre></div></div> <p>When RubyGems activates a gem, it adds your package’s <code class="language-plaintext highlighter-rouge">lib</code> folder to the <code class="language-plaintext highlighter-rouge">$LOAD_PATH</code> ready to be required normally by another lib or application. It is safe to assume you can then <code class="language-plaintext highlighter-rouge">require</code> any file in your <code class="language-plaintext highlighter-rouge">lib</code> folder.</p> <h2 id="prerelease-gems">Prerelease gems</h2> <p>Many gem developers have versions of their gem ready to go out for testing or “edge” releases before a big gem release. RubyGems supports the concept of “prerelease” versions, which could be betas, alphas, or anything else that isn’t ready as a regular release.</p> <p>Taking advantage of this is easy. All you need is one or more letters in the gem version. For example, here’s what a prerelease gemspec’s <code class="language-plaintext highlighter-rouge">version</code> field might look like:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Gem::Specification.new do |s| s.name = "hola" s.version = "1.0.0.pre" </code></pre></div></div> <p>Other prerelease version numbers might include <code class="language-plaintext highlighter-rouge">2.0.0.rc1</code>, or <code class="language-plaintext highlighter-rouge">1.5.0.beta.3</code>. It just has to have a letter in it, and you’re set. These gems can then be installed with the <code class="language-plaintext highlighter-rouge">--pre</code> flag, like so:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>% gem list factory_bot -r --pre *** REMOTE GEMS *** factory_bot (2.0.0.beta2, 2.0.0.beta1) factory_bot_rails (1.1.beta1) % gem install factory_bot --pre Successfully installed factory_bot-2.0.0.beta2 1 gem installed </code></pre></div></div> <h2 id="credits">Credits</h2> <p>Several sources were used for content for this guide:</p> <ul> <li><a href="https://yehudakatz.com/2009/07/24/rubygems-good-practice/">Rubygems Good Practice</a></li> <li><a href="https://weblog.rubyonrails.org/2009/9/1/gem-packaging-best-practices">Gem Packaging: Best Practices</a></li> </ul> </div> </div> </div> <div class="paginated-nav-links"> <a class="paginated-nav-link--prev" data-icon="&lt;" href="/ssl-certificate-update"> <span>Previous</span> </a> <a class="paginated-nav-link--next" data-icon="&gt;" href="/specification-reference"> <span>Next</span> </a> </div> </div> </main> <footer class="footer"> <div class="l-wrap--footer"> <div class="l-overflow"> <div class="nav--v l-col--r--pad"> <a class="nav--v__link--footer" href="https://status.rubygems.org/">Status</a> <a class="nav--v__link--footer" href="http://uptime.rubygems.org/">Uptime</a> <a class="nav--v__link--footer" href="https://github.com/rubygems/rubygems.org" target='_blank'>Code</a> <a class="nav--v__link--footer" href="https://groups.google.com/forum/#!forum/rubygems-org" target='_blank'>Discuss</a> <a class="nav--v__link--footer" href="https://rubygems.org/stats">Stats</a> <a class="nav--v__link--footer" href="https://blog.rubygems.org/">Blog</a> <a class="nav--v__link--footer" href="https://rubygems.org/pages/about">About</a> <a class="nav--v__link--footer" href="mailto:support@rubygems.org">Help</a> </div> <div class="l-colspan--l colspan--l--has-border"> <p class="footer__about">RubyGems.org is the Ruby community&rsquo;s gem hosting service. Instantly publish your gems and install them. Use the API to interact and find out more information about available gems. Become a contributor and enhance the site with your own changes.</p> </div> </div> </div> <div class="footer__sponsors-wrap"> <div class="footer__sponsors"> <a class="footer__sponsor footer__sponsor__ruby_central" href="https://rubycentral.org/" target="_blank" rel="noreferrer"> Supported by <span class="t-hidden">Ruby Central</span> </a> <a class="footer__sponsor footer__sponsor__dockyard" href="https://dockyard.com/ruby-on-rails-consulting" target="_blank" rel="noreferrer"> Designed by <span class="t-hidden">DockYard</span> </a> <a class="footer__sponsor footer__sponsor__dnsimple" href="https://dnsimple.link/resolving-rubygems" target="_blank" rel="noreferrer"> Resolved with <span class="t-hidden">DNSimple</span> </a> <a class="footer__sponsor footer__sponsor__datadog" href="https://www.datadoghq.com/" target="_blank" rel="noreferrer"> Monitored by <span class="t-hidden">Datadog</span> </a> <a class="footer__sponsor footer__sponsor__fastly" href="https://www.fastly.com/" target="_blank" rel="noreferrer"> Gems served by <span class="t-hidden">Fastly</span> </a> <a class="footer__sponsor footer__sponsor__honeybadger" href="https://www.honeybadger.io/" target="_blank" rel="noreferrer"> Monitored by <span class="t-hidden">Honeybadger</span> </a> <a class="footer__sponsor footer__sponsor__domainr" href="https://domainr.com/" target="_blank" rel="noreferrer"> Verified by <span class="t-hidden">Domainr</span> </a> <a class="footer__sponsor footer__sponsor__whitesource" href="https://www.whitesourcesoftware.com/" target="_blank" rel="noreferrer"> Secured by <span class="t-hidden">Whitesource</span> </a> </div> </div> </footer> <script type="text/javascript"> var _gaq = _gaq || []; _gaq.push(['_setAccount', 'UA-10315684-2']); _gaq.push(['_trackPageview']); (function() { var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true; ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js'; var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s); })(); </script> </body> </html>

Pages: 1 2 3 4 5 6 7 8 9 10