hybridgroup-octokit 0.6.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.document +4 -0
- data/.gemtest +0 -0
- data/.gitignore +24 -0
- data/.rspec +3 -0
- data/.travis.yml +6 -0
- data/Gemfile +3 -0
- data/LICENSE +20 -0
- data/README.markdown +73 -0
- data/Rakefile +8 -0
- data/changelog.markdown +42 -0
- data/lib/faraday/response/raise_error.rb +33 -0
- data/lib/octokit/client/authentication.rb +23 -0
- data/lib/octokit/client/commits.rb +16 -0
- data/lib/octokit/client/connection.rb +34 -0
- data/lib/octokit/client/issues.rb +60 -0
- data/lib/octokit/client/network.rb +15 -0
- data/lib/octokit/client/objects.rb +33 -0
- data/lib/octokit/client/organizations.rb +90 -0
- data/lib/octokit/client/pulls.rb +25 -0
- data/lib/octokit/client/repositories.rb +138 -0
- data/lib/octokit/client/request.rb +41 -0
- data/lib/octokit/client/timelines.rb +22 -0
- data/lib/octokit/client/users.rb +75 -0
- data/lib/octokit/client.rb +40 -0
- data/lib/octokit/configuration.rb +61 -0
- data/lib/octokit/repository.rb +39 -0
- data/lib/octokit/version.rb +3 -0
- data/lib/octokit.rb +53 -0
- data/octokit.gemspec +33 -0
- data/spec/faraday/response_spec.rb +34 -0
- data/spec/fixtures/blob.json +1 -0
- data/spec/fixtures/blob_metadata.json +1 -0
- data/spec/fixtures/blobs.json +1 -0
- data/spec/fixtures/branches.json +1 -0
- data/spec/fixtures/collaborators.json +1 -0
- data/spec/fixtures/comment.json +1 -0
- data/spec/fixtures/comments.json +1 -0
- data/spec/fixtures/commit.json +1 -0
- data/spec/fixtures/commits.json +1 -0
- data/spec/fixtures/contributors.json +1 -0
- data/spec/fixtures/delete_token.json +1 -0
- data/spec/fixtures/emails.json +1 -0
- data/spec/fixtures/followers.json +1 -0
- data/spec/fixtures/following.json +1 -0
- data/spec/fixtures/issue.json +1 -0
- data/spec/fixtures/issues.json +1 -0
- data/spec/fixtures/labels.json +1 -0
- data/spec/fixtures/languages.json +1 -0
- data/spec/fixtures/network.json +1 -0
- data/spec/fixtures/network_data.json +1 -0
- data/spec/fixtures/network_meta.json +1 -0
- data/spec/fixtures/organization.json +1 -0
- data/spec/fixtures/organizations.json +1 -0
- data/spec/fixtures/public_keys.json +1 -0
- data/spec/fixtures/pull.json +1 -0
- data/spec/fixtures/pulls.json +1 -0
- data/spec/fixtures/raw.txt +7 -0
- data/spec/fixtures/repositories.json +1 -0
- data/spec/fixtures/repository.json +1 -0
- data/spec/fixtures/tags.json +1 -0
- data/spec/fixtures/team.json +1 -0
- data/spec/fixtures/teams.json +1 -0
- data/spec/fixtures/timeline.json +1237 -0
- data/spec/fixtures/tree.json +1 -0
- data/spec/fixtures/tree_metadata.json +1 -0
- data/spec/fixtures/user.json +1 -0
- data/spec/fixtures/users.json +1 -0
- data/spec/fixtures/watchers.json +1 -0
- data/spec/helper.rb +64 -0
- data/spec/octokit/client/commits_spec.rb +32 -0
- data/spec/octokit/client/issues_spec.rb +154 -0
- data/spec/octokit/client/network_spec.rb +32 -0
- data/spec/octokit/client/objects_spec.rb +81 -0
- data/spec/octokit/client/organizations_spec.rb +234 -0
- data/spec/octokit/client/pulls_spec.rb +44 -0
- data/spec/octokit/client/repositories_spec.rb +331 -0
- data/spec/octokit/client/timelines_spec.rb +42 -0
- data/spec/octokit/client/users_spec.rb +274 -0
- data/spec/octokit/client_spec.rb +12 -0
- data/spec/octokit_spec.rb +15 -0
- data/spec/repository_spec.rb +54 -0
- metadata +403 -0
@@ -0,0 +1,41 @@
|
|
1
|
+
module Octokit
|
2
|
+
class Client
|
3
|
+
module Request
|
4
|
+
def get(path, options={}, raw=false, format_path=true, authenticate=true)
|
5
|
+
request(:get, path, options, raw, format_path, authenticate)
|
6
|
+
end
|
7
|
+
|
8
|
+
def post(path, options={}, raw=false, format_path=true, authenticate=true)
|
9
|
+
request(:post, path, options, raw, format_path, authenticate)
|
10
|
+
end
|
11
|
+
|
12
|
+
def put(path, options={}, raw=false, format_path=true, authenticate=true)
|
13
|
+
request(:put, path, options, raw, format_path, authenticate)
|
14
|
+
end
|
15
|
+
|
16
|
+
def delete(path, options={}, raw=false, format_path=true, authenticate=true)
|
17
|
+
request(:delete, path, options, raw, format_path, authenticate)
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def request(method, path, options, raw, format_path, authenticate)
|
23
|
+
response = connection(raw, authenticate).send(method) do |request|
|
24
|
+
path = formatted_path(path) if format_path
|
25
|
+
case method
|
26
|
+
when :get, :delete
|
27
|
+
request.url(path, options)
|
28
|
+
when :post, :put
|
29
|
+
request.path = path
|
30
|
+
request.body = options unless options.empty?
|
31
|
+
end
|
32
|
+
end
|
33
|
+
raw ? response : response.body
|
34
|
+
end
|
35
|
+
|
36
|
+
def formatted_path(path)
|
37
|
+
['api', ['v', version].join, format, path].compact.join('/')
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Octokit
|
2
|
+
class Client
|
3
|
+
module Timelines
|
4
|
+
|
5
|
+
def timeline(options={})
|
6
|
+
path = "https://github.com/timeline.json"
|
7
|
+
get(path, options, false, false, false)
|
8
|
+
end
|
9
|
+
|
10
|
+
def user_timeline(username=login, options={})
|
11
|
+
if token
|
12
|
+
path = "https://github.com/#{username}.private.json"
|
13
|
+
options[:token] = token
|
14
|
+
else
|
15
|
+
path = "https://github.com/#{username}.json"
|
16
|
+
end
|
17
|
+
get(path, options, false, false, false)
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
module Octokit
|
2
|
+
class Client
|
3
|
+
module Users
|
4
|
+
EMAIL_RE = /[\w.!#\$%+-]+@[\w-]+(?:\.[\w-]+)+/
|
5
|
+
|
6
|
+
def search_users(search, options={})
|
7
|
+
if search.match(EMAIL_RE)
|
8
|
+
get("user/email/#{search}", options)['user']
|
9
|
+
else
|
10
|
+
get("user/search/#{search}", options)['users']
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def user(username=nil, options={})
|
15
|
+
get(["user/show", username].compact.join('/'), options)['user']
|
16
|
+
end
|
17
|
+
|
18
|
+
def update_user(values, options={})
|
19
|
+
post("user/show/#{login}", options.merge({:values => values}))['user']
|
20
|
+
end
|
21
|
+
|
22
|
+
def followers(user=login, options={})
|
23
|
+
get("user/show/#{user}/followers", options)['users']
|
24
|
+
end
|
25
|
+
|
26
|
+
def following(user=login, options={})
|
27
|
+
get("user/show/#{user}/following", options)['users']
|
28
|
+
end
|
29
|
+
|
30
|
+
def follows?(*args)
|
31
|
+
target = args.pop
|
32
|
+
user = args.first
|
33
|
+
user ||= login
|
34
|
+
return if user.nil?
|
35
|
+
following(user).include?(target)
|
36
|
+
end
|
37
|
+
|
38
|
+
def follow(user, options={})
|
39
|
+
post("user/follow/#{user}", options)['users']
|
40
|
+
end
|
41
|
+
|
42
|
+
def unfollow(user, options={})
|
43
|
+
post("user/unfollow/#{user}", options)['users']
|
44
|
+
end
|
45
|
+
|
46
|
+
def watched(user=login, options={})
|
47
|
+
get("repos/watched/#{user}", options)['repositories']
|
48
|
+
end
|
49
|
+
|
50
|
+
def keys(options={})
|
51
|
+
get("user/keys", options)['public_keys']
|
52
|
+
end
|
53
|
+
|
54
|
+
def add_key(title, key, options={})
|
55
|
+
post("user/key/add", options.merge({:title => title, :key => key}))['public_keys']
|
56
|
+
end
|
57
|
+
|
58
|
+
def remove_key(id, options={})
|
59
|
+
post("user/key/remove", options.merge({:id => id}))['public_keys']
|
60
|
+
end
|
61
|
+
|
62
|
+
def emails(options={})
|
63
|
+
get("user/emails", options)['emails']
|
64
|
+
end
|
65
|
+
|
66
|
+
def add_email(email, options={})
|
67
|
+
post("user/email/add", options.merge({:email => email}))['emails']
|
68
|
+
end
|
69
|
+
|
70
|
+
def remove_email(email, options={})
|
71
|
+
post("user/email/remove", options.merge({:email => email}))['emails']
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'octokit/repository'
|
2
|
+
require 'octokit/client/authentication'
|
3
|
+
require 'octokit/client/connection'
|
4
|
+
require 'octokit/client/request'
|
5
|
+
require 'octokit/client/commits'
|
6
|
+
require 'octokit/client/issues'
|
7
|
+
require 'octokit/client/network'
|
8
|
+
require 'octokit/client/objects'
|
9
|
+
require 'octokit/client/organizations'
|
10
|
+
require 'octokit/client/pulls'
|
11
|
+
require 'octokit/client/repositories'
|
12
|
+
require 'octokit/client/timelines'
|
13
|
+
require 'octokit/client/users'
|
14
|
+
|
15
|
+
module Octokit
|
16
|
+
class Client
|
17
|
+
attr_accessor *Configuration::VALID_OPTIONS_KEYS
|
18
|
+
|
19
|
+
def initialize(options={})
|
20
|
+
options = Octokit.options.merge(options)
|
21
|
+
Configuration::VALID_OPTIONS_KEYS.each do |key|
|
22
|
+
send("#{key}=", options[key])
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
include Octokit::Client::Authentication
|
27
|
+
include Octokit::Client::Connection
|
28
|
+
include Octokit::Client::Request
|
29
|
+
|
30
|
+
include Octokit::Client::Commits
|
31
|
+
include Octokit::Client::Issues
|
32
|
+
include Octokit::Client::Network
|
33
|
+
include Octokit::Client::Objects
|
34
|
+
include Octokit::Client::Organizations
|
35
|
+
include Octokit::Client::Pulls
|
36
|
+
include Octokit::Client::Repositories
|
37
|
+
include Octokit::Client::Timelines
|
38
|
+
include Octokit::Client::Users
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
require 'faraday'
|
2
|
+
require 'octokit/version'
|
3
|
+
|
4
|
+
module Octokit
|
5
|
+
module Configuration
|
6
|
+
VALID_OPTIONS_KEYS = [
|
7
|
+
:adapter,
|
8
|
+
:endpoint,
|
9
|
+
:format,
|
10
|
+
:login,
|
11
|
+
:password,
|
12
|
+
:proxy,
|
13
|
+
:token,
|
14
|
+
:oauth_token,
|
15
|
+
:user_agent,
|
16
|
+
:version].freeze
|
17
|
+
|
18
|
+
VALID_FORMATS = [
|
19
|
+
:json,
|
20
|
+
:xml,
|
21
|
+
:yaml].freeze
|
22
|
+
|
23
|
+
DEFAULT_ADAPTER = Faraday.default_adapter
|
24
|
+
DEFAULT_ENDPOINT = 'https://github.com/'.freeze
|
25
|
+
DEFAULT_FORMAT = :json
|
26
|
+
DEFAULT_LOGIN = nil
|
27
|
+
DEFAULT_PASSWORD = nil
|
28
|
+
DEFAULT_PROXY = nil
|
29
|
+
DEFAULT_TOKEN = nil
|
30
|
+
DEFAULT_OAUTH_TOKEN = nil
|
31
|
+
DEFAULT_USER_AGENT = "Octokit Ruby Gem #{Octokit::VERSION}".freeze
|
32
|
+
DEFAULT_VERSION = 2
|
33
|
+
|
34
|
+
attr_accessor *VALID_OPTIONS_KEYS
|
35
|
+
|
36
|
+
def self.extended(base)
|
37
|
+
base.reset
|
38
|
+
end
|
39
|
+
|
40
|
+
def configure
|
41
|
+
yield self
|
42
|
+
end
|
43
|
+
|
44
|
+
def options
|
45
|
+
VALID_OPTIONS_KEYS.inject({}){|o,k| o.merge!(k => send(k)) }
|
46
|
+
end
|
47
|
+
|
48
|
+
def reset
|
49
|
+
self.adapter = DEFAULT_ADAPTER
|
50
|
+
self.endpoint = DEFAULT_ENDPOINT
|
51
|
+
self.format = DEFAULT_FORMAT
|
52
|
+
self.login = DEFAULT_LOGIN
|
53
|
+
self.password = DEFAULT_PASSWORD
|
54
|
+
self.proxy = DEFAULT_PROXY
|
55
|
+
self.token = DEFAULT_TOKEN
|
56
|
+
self.oauth_token = DEFAULT_OAUTH_TOKEN
|
57
|
+
self.user_agent = DEFAULT_USER_AGENT
|
58
|
+
self.version = DEFAULT_VERSION
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'addressable/uri'
|
2
|
+
|
3
|
+
module Octokit
|
4
|
+
class Repository
|
5
|
+
attr_accessor :username, :name
|
6
|
+
|
7
|
+
def self.from_url(url)
|
8
|
+
Repository.new(Addressable::URI.parse(url).path[1..-1])
|
9
|
+
end
|
10
|
+
|
11
|
+
def initialize(repo)
|
12
|
+
case repo
|
13
|
+
when String
|
14
|
+
@username, @name = repo.split('/')
|
15
|
+
when Repository
|
16
|
+
@username = repo.username
|
17
|
+
@name = repo.name
|
18
|
+
when Hash
|
19
|
+
@name = repo[:repo] ||= repo[:name]
|
20
|
+
@username = repo[:username] ||= repo[:user] ||= repo[:owner]
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def slug
|
25
|
+
[@username, @name].compact.join('/')
|
26
|
+
end
|
27
|
+
|
28
|
+
def to_s
|
29
|
+
self.slug
|
30
|
+
end
|
31
|
+
|
32
|
+
def url
|
33
|
+
"https://github.com/#{slug}"
|
34
|
+
end
|
35
|
+
|
36
|
+
alias :user :username
|
37
|
+
alias :repo :name
|
38
|
+
end
|
39
|
+
end
|
data/lib/octokit.rb
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'octokit/configuration'
|
2
|
+
require 'octokit/client'
|
3
|
+
|
4
|
+
module Octokit
|
5
|
+
extend Configuration
|
6
|
+
|
7
|
+
# Alias for Octokit::Client.new
|
8
|
+
#
|
9
|
+
# @return [Octokit::Client]
|
10
|
+
def self.client(options={})
|
11
|
+
Octokit::Client.new(options)
|
12
|
+
end
|
13
|
+
|
14
|
+
# Delegate to Octokit::Client.new
|
15
|
+
def self.method_missing(method, *args, &block)
|
16
|
+
return super unless client.respond_to?(method)
|
17
|
+
client.send(method, *args, &block)
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.respond_to?(method)
|
21
|
+
client.respond_to?(method) || super
|
22
|
+
end
|
23
|
+
|
24
|
+
# Custom error class for rescuing from all GitHub errors
|
25
|
+
class Error < StandardError; end
|
26
|
+
|
27
|
+
# Raised when GitHub returns a 400 HTTP status code
|
28
|
+
class BadRequest < Error; end
|
29
|
+
|
30
|
+
# Raised when GitHub returns a 401 HTTP status code
|
31
|
+
class Unauthorized < Error; end
|
32
|
+
|
33
|
+
# Raised when GitHub returns a 403 HTTP status code
|
34
|
+
class Forbidden < Error; end
|
35
|
+
|
36
|
+
# Raised when GitHub returns a 404 HTTP status code
|
37
|
+
class NotFound < Error; end
|
38
|
+
|
39
|
+
# Raised when GitHub returns a 406 HTTP status code
|
40
|
+
class NotAcceptable < Error; end
|
41
|
+
|
42
|
+
# Raised when GitHub returns a 500 HTTP status code
|
43
|
+
class InternalServerError < Error; end
|
44
|
+
|
45
|
+
# Raised when GitHub returns a 501 HTTP status code
|
46
|
+
class NotImplemented < Error; end
|
47
|
+
|
48
|
+
# Raised when GitHub returns a 502 HTTP status code
|
49
|
+
class BadGateway < Error; end
|
50
|
+
|
51
|
+
# Raised when GitHub returns a 503 HTTP status code
|
52
|
+
class ServiceUnavailable < Error; end
|
53
|
+
end
|
data/octokit.gemspec
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
|
2
|
+
# -*- encoding: utf-8 -*-
|
3
|
+
require File.expand_path('../lib/octokit/version', __FILE__)
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.add_development_dependency('json_pure', '~> 1.5')
|
7
|
+
s.add_development_dependency('nokogiri', '~> 1.4')
|
8
|
+
s.add_development_dependency('rake', '~> 0.8')
|
9
|
+
s.add_development_dependency('rspec', '~> 2.5')
|
10
|
+
s.add_development_dependency('simplecov', '~> 0.4')
|
11
|
+
s.add_development_dependency('webmock', '~> 1.6')
|
12
|
+
s.add_development_dependency('ZenTest', '~> 4.5')
|
13
|
+
s.add_runtime_dependency('addressable', '~> 2.2.4')
|
14
|
+
s.add_runtime_dependency('hashie', '~> 1.0.0')
|
15
|
+
s.add_runtime_dependency('faraday', '~> 0.6.0')
|
16
|
+
s.add_runtime_dependency('faraday_middleware', '~> 0.6.0')
|
17
|
+
s.add_runtime_dependency('jruby-openssl', '~> 0.7.3') if RUBY_PLATFORM == 'java'
|
18
|
+
s.add_runtime_dependency('multi_json', '~> 0.0.5')
|
19
|
+
s.add_runtime_dependency('multi_xml', '~> 0.2.0')
|
20
|
+
s.name = 'hybridgroup-octokit'
|
21
|
+
s.authors = ["Wynn Netherland", "Adam Stacoviak", "Erik Michaels-Ober"]
|
22
|
+
s.description = %q{Simple wrapper for the GitHub API v2}
|
23
|
+
s.email = ['wynn.netherland@gmail.com']
|
24
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{|f| File.basename(f)}
|
25
|
+
s.files = `git ls-files`.split("\n")
|
26
|
+
s.homepage = 'http://wynnnetherland.com/projects/octokit/'
|
27
|
+
s.require_paths = ['lib']
|
28
|
+
s.summary = %q{Wrapper for the GitHub API}
|
29
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
30
|
+
s.version = Octokit::VERSION.dup
|
31
|
+
s.platform = Gem::Platform::RUBY
|
32
|
+
s.required_rubygems_version = Gem::Requirement.new('>= 1.3.6') if s.respond_to? :required_rubygems_version=
|
33
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require 'helper'
|
3
|
+
|
4
|
+
describe Faraday::Response do
|
5
|
+
before do
|
6
|
+
@client = Octokit::Client.new
|
7
|
+
end
|
8
|
+
|
9
|
+
{
|
10
|
+
400 => Octokit::BadRequest,
|
11
|
+
401 => Octokit::Unauthorized,
|
12
|
+
403 => Octokit::Forbidden,
|
13
|
+
404 => Octokit::NotFound,
|
14
|
+
406 => Octokit::NotAcceptable,
|
15
|
+
500 => Octokit::InternalServerError,
|
16
|
+
501 => Octokit::NotImplemented,
|
17
|
+
502 => Octokit::BadGateway,
|
18
|
+
503 => Octokit::ServiceUnavailable,
|
19
|
+
}.each do |status, exception|
|
20
|
+
context "when HTTP status is #{status}" do
|
21
|
+
|
22
|
+
before do
|
23
|
+
stub_get('user/show/sferik').
|
24
|
+
to_return(:status => status)
|
25
|
+
end
|
26
|
+
|
27
|
+
it "should raise #{exception.name} error" do
|
28
|
+
lambda do
|
29
|
+
@client.user('sferik')
|
30
|
+
end.should raise_error(exception,/.*/)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
{"blob":{"name":"README.mkd","data":"RailsAdmin\n==========\nRailsAdmin is a Rails engine that provides an easy-to-use interface for managing your data.\n\nRailsAdmin started as a port of [MerbAdmin](http://github.com/sferik/merb-admin) to Rails 3\nand was implemented as a [Ruby Summer of Code project](http://www.rubysoc.org/projects)\nby [Bogdan Gaza](http://github.com/hurrycane) with mentors [Erik Michaels-Ober](http://github.com/sferik),\n[Yehuda Katz](http://github.com/wycats),\n[Luke van der Hoeven](http://github.com/plukevdh), and [Rein Henrichs](http://github.com/reinh).\n\nIt currently offers the following features:\n\n* Display database tables\n* Create new data\n* Easily update data\n* Safely delete data\n* Automatic form validation\n* Search\n* Authentication (via [Devise](http://github.com/plataformatec/devise))\n* User action history\n\nSupported ORMs:\n\n* ActiveRecord\n\n_[Information](https://github.com/sferik/rails_admin/issues/105) about support for other ORMs._\n\nHelp\n----\nIf you have a question, you can ask the [official RailsAdmin mailing list](http://groups.google.com/group/rails_admin)\nor ping sferik on IRC in [#railsadmin on irc.freenode.net](http://webchat.freenode.net/?channels=railsadmin).\n\nScreenshots\n-----------\n![List view](https://github.com/sferik/rails_admin/raw/master/screenshots/list.png \"List view\")\n![Edit view](https://github.com/sferik/rails_admin/raw/master/screenshots/edit.png \"Edit view\")\n\nInstallation\n------------\nIn your `Gemfile`, add the following dependency:\n gem 'devise' # Devise must be required before RailsAdmin\n gem 'rails_admin', :git => 'git://github.com/sferik/rails_admin.git'\nRun:\n $ bundle install\nAnd then run:\n $ rails generate rails_admin:install_admin\nThis task will install RailsAdmin and [Devise](http://github.com/plataformatec/devise) if you\ndon't already have it installed. [Devise](http://github.com/plataformatec/devise) is strongly\nrecommended to protect your data from anonymous users.\n\nIf you plan to use Devise, but want to use a custom model for authentication\n(default is User) you can provide that as an argument for the installer. For example\nto override the default with a Member model run:\n $ rails generate rails_admin:install_admin member\n\nIf you want to use the CKEditor, you need to [download it](http://ckeditor.com/download) from source\nand unpack the 'ckeditor' folder into your default 'public/javascripts' folder. If you're using any\nnon-Windows system, you can try to use the automatic downloader:\n $ rake admin:ckeditor_download\n\nWhen running RailsAdmin in production the images, stylesheets, and javascript assets may return 404\nnot found error's depending on your servers static assets configuration. To prevent this issue you\ncan copy assets directly into your application by running:\n $ rake admin:copy_assets\n \nUsage\n-----\nStart the server:\n $ rails server\nYou should now be able to administer your site at <http://localhost:3000/admin>\n\nConfiguration\n-------------\nRailsAdmin provides its out of the box administrative interface by inspecting your application's\nmodels and following some Rails conventions. For a more tailored experience, it also provides a\nconfiguration DSL which allows you to customize many aspects of the interface.\n\nThe configuration code should be placed in an initializer file, for example:\n config/initializers/rails_admin.rb\n\n### General\n\nYou can customize authentication by providing a custom block for `RailsAdmin.authenticate_with`.\nTo disable authentication, pass an empty block:\n\n RailsAdmin.authenticate_with {}\n\nYou can exclude models from RailsAdmin by appending those models to `excluded_models`:\n\n RailsAdmin.config do |config|\n config.excluded_models << ClassName\n end\n\n### Navigation ###\n\n* hiding a model\n* setting the model's label\n* configuring the number of visible tabs\n\n**Hiding a model**\n\nYou can hide a model from the top navigation by marking its `visible` option\nas false within the model's navigation configuration section:\n\nBy passing the value as an argument:\n\n RailsAdmin.config do |config|\n config.model Team do\n navigation do\n visible false\n end\n end\n end\n\nOr by passing a block that will be lazy evaluated each time the option is read:\n\n RailsAdmin.config do |config|\n config.model Team do\n navigation do\n visible { false }\n end\n end\n end\n\nThese two examples also work as a generic example of how most of the\nconfiguration options function within RailsAdmin. You can pass a value as an\nargument `option_name value`, or you can pass in a block which will be\nevaluated each time the option is read. Notable is that boolean options' reader\naccessors will be appended with ? whereas the writers will not be. That is, if\nyou want to get the Team model's visibility in navigation, you use\n`RailsAdmin.config(Team).navigation.visible?`.\n\nBack to navigation configuration - there is also an alias method that can be used:\n\n RailsAdmin.config do |config|\n config.model Team do\n hide_from_navigation\n end\n end\n\nAnd also a reverse alias method to make it visible again:\n\n RailsAdmin.config do |config|\n config.model Team do\n show_in_navigation\n end\n end\n\nBoth also accept a block:\n\n RailsAdmin.config do |config|\n config.model Team do\n # Hide Team from navigation on Sundays\n hide_from_navigation do\n Time.now.wday == 0\n end\n end\n end\n\n*NOTE* - The hide_from_navigation method was originally implemented as\n hide_in_navigation but that name is now deprecated - you should\n change your code to use hide_from_navigation.\n\n**Setting the model's label**\n\nIf you need to customize the label of the model within the navigation tab, use:\n\n RailsAdmin.config do |config|\n config.model Team do\n navigation do\n label \"List of teams\"\n end\n end\n end\n\nRemember, you can also pass the value as an argument or as a block as with the\nbefore mentioned visibility options. Besides that, the label also has a\nshorthand syntax:\n\n RailsAdmin.config do |config|\n config.model Team do\n label_for_navigation \"List of teams\"\n end\n end\n\nwhich allows both forms of configuration value passing as well.\n\n**Configuring the number of visible tabs**\n\nYou can configure the number of tabs visible in the top navigation:\n\n RailsAdmin.config do |config|\n config.navigation.max_visible_tabs 3\n end\n\nLinks to the rest of the models will be rendered in a drop down menu next to the\ntabs. Even though this option is not model specific, it shares the same\nsemantics as the earlier ones - you can also pass in a block or pass the value\nas an argument by omitting the equals sign.\n\n### List view\n\n* Number of items per page\n* Number of items per page per model\n* Fields\n * Visibility and ordering\n * Label\n * Output formatting\n * Sortability\n * Column CSS class\n * Column width\n * The object_label method\n\n**Number of items per page**\n\nYou can configure the default number of rows rendered per page:\n\n RailsAdmin.config do |config|\n config.list.default_items_per_page = 50\n end\n\n**Number of items per page per model**\n\nYou can also configure it per model:\n\n RailsAdmin.config do |config|\n config.model Team do\n list do\n items_per_page 100\n end\n end\n end\n\n**Fields - Visibility and ordering**\n\nBy default all fields are visible, but they are not presented in any particular\norder. If you specifically declare fields, only defined fields will be visible\nand they will be presented in the order defined:\n\n RailsAdmin.config do |config|\n config.model Team do\n list do\n field :name\n field :created_at\n end\n end\n end\n\nThis would show only \"name\" and \"created at\" columns in the list view.\n\nIf you need to hide fields based on some logic on runtime (for instance\nauthorization to view field) you can pass a block for the `visible` option\n(including its `hide` and `show` accessors):\n\n RailsAdmin.config do |config|\n config.model Team do\n list do\n field :name\n field :created_at\n field :revenue do\n visible do\n current_user.roles.include?(:accounting) # metacode\n end\n end\n end\n end\n end\n\nNote that above example's authorization conditional is not runnable code, just\nan imaginary example. You need to provide RailsAdmin with your own\nauthorization scheme for which you can find a guide at the end of this file.\n\n**Fields - Label**\n\nThe header of a list view column can be changed with the familiar label method:\n\n RailsAdmin.config do |config|\n config.model Team do\n list do\n field :name do\n label \"Title\"\n end\n field :created_at do\n label \"Created on\"\n end\n end\n end\n end\n\nAs in the previous example this would show only columns for fields \"name\" and\n\"created at\" and their headers would have been renamed to \"Title\" and\n\"Created on\".\n\n**Fields - Output formatting**\n\nThe field's output can be modified:\n\n RailsAdmin.config do |config|\n config.model Team do\n list do\n field :name do\n formatted_value do\n value.to_s.upcase\n end\n end\n field :created_at\n end\n end\n end\n\nThis would render all the teams' names uppercased.\n\nThe field declarations also have access to a bindings hash which contains the\ncurrent record instance in key :object and the view instance in key :view.\nVia :object we can access other columns' values and via :view we can access our\napplication's view helpers:\n\n RailsAdmin.config do |config|\n config.model Team do\n list do\n field :name do\n formatted_value do\n bindings[:view].tag(:img, { :src => bindings[:object].logo_url }) << value\n end\n end\n field :created_at\n end\n end\n end\n\nThis would output the name column prepended with team's logo using the `tag`\nview helper. This example uses `value` method to access the name field's value,\nbut that could be written more verbosely as `bindings[:object].name`.\n\nFields of different date types (date, datetime, time, timestamp) have two extra\noptions to set the time formatting:\n\n RailsAdmin.config do |config|\n config.model Team do\n list do\n field :name\n field :created_at do\n date_format :short\n end\n field :updated_at do\n strftime_format \"%Y-%m-%d\"\n end\n end\n end\n end\n\nThis would render all the teams' \"created at\" dates in the short format of your\napplication's locale and \"updated at\" dates in format YYYY-MM-DD. If both\noptions are defined for a single field, `strftime_format` has precedence over\n`date_format` option. For more information about localizing Rails see\n[Rails Internationalization API](http://edgeguides.rubyonrails.org/i18n.html#adding-date-time-formats)\nand [Rails I18n repository](https://github.com/svenfuchs/rails-i18n/tree/master/rails/locale).\n\n**Fields - Sortability**\n\nYou can make a column non-sortable by setting the sortable option to false:\n\n RailsAdmin.config do |config|\n config.model Team do\n list do\n field :name\n field :created_at do\n sortable false\n end\n end\n end\n end\n\n**Fields - Column CSS class**\n\nBy default each column has a CSS class set according to field's data type. You\ncan customize this by:\n\n RailsAdmin.config do |config|\n config.model Team do\n list do\n field :name\n field :created_at do\n css_class \"customClass\"\n end\n end\n end\n end\n\nThis would render the \"created at\" field's header and body columns with a CSS class named\n\"customClass\".\n\n**Fields - Column width**\n\nBy default columns' widths are calculated from certain pre-defined,\ndata-type-specific pixel values. If you want to ensure a minimum width for a\ncolumn, you can:\n\n RailsAdmin.config do |config|\n config.model Team do\n list do\n field :name do\n column_width 200\n end\n field :created_at\n end\n end\n end\n\n**Fields - The object_label method**\n\nList section has a configuration option `object_label` which configures\nthe title of a single database record.\n\nBy default it queries if the record in question has columns named \"name\" or\n\"title\". If neither is found it returns the model's classname appended with its\ndatabase identifier.\n\nThis value is used in a number of places in RailsAdmin - for instance as the\noutput of belongs to associations in the listing views of related models, as\nthe option labels of the relational fields' input widgets in the edit views of\nrelated models and as part of the audit information stored in the history\nrecords - so keep in mind that this configuration option has widespread\neffects.\n\n RailsAdmin.config do |config|\n config.model Team do\n list do\n object_label do\n \"#{bindings[:object].name} - #{bindings[:object].league.name}\"\n end\n end\n end\n end\n\nThis would output \"Team's name - Team's league's name\" in all the places\nmentioned in paragraph above example.\n\n### Create and update views\n\n* Field groupings\n * Visibility\n * Labels\n * Syntax\n* Fields\n * Rendering\n * Overriding field type\n * Available field types\n * Creating a custom field type\n * Creating a custom field factory\n\n**Field groupings**\n\nBy default RailsAdmin groups fields in the edit views (create and update views)\nby including all database columns and belongs to associations to \"Basic info\"\ngroup which is displayed on top of form. Below that are displayed all the other\nassociations a model has, one group per association.\n\nThe configuration accessors are `edit`, `create` and `update`. First one is a\nbatch accessor which configures both create and update views. For consistency,\nthese examples only include the batch accessor `edit`, but if you need differing\ncreate and update views just replace `edit` with `create` or `update`.\n\n**Field groupings - visibility**\n\nField groups can be hidden:\n\n RailsAdmin.config do |config|\n config.model Team do\n edit do\n group :default do\n hide\n end\n end\n end\n end\n\nThis would hide the \"Basic info\" group which is accessed by the symbol :default.\nAssociations' groups can be accessed by the name of the association, such as\n:fans or :players. The hide method is just a shortcut for the actual `visible`\noption which was mentioned in the beginning of the navigation section.\n\n**Field groupings - labels**\n\nField groups can be renamed:\n\n RailsAdmin.config do |config|\n config.model Team do\n edit do\n group :default do\n label \"Team information\"\n end\n end\n end\n end\n\nThis would render \"Team information\" instead of \"Basic info\" as the groups label.\n\n**Field groupings - syntax**\n\nAs in the list view, the edit views' configuration blocks can directly\ncontain field configurations, but in edit views those configurations can\nalso be nested within group configurations. Below examples result an\nequal configuration:\n\n RailsAdmin.config do |config|\n config.model Team do\n edit do\n group :default do\n label \"Default group\"\n end\n field :name do\n label \"Title\"\n group :default\n end\n end\n end\n end\n\n RailsAdmin.config do |config|\n config.model Team do\n edit do\n group :default do\n label \"Default group\"\n field :name do\n label \"Title\"\n end\n end\n end\n end\n end\n\nIn fact the first examples `group :default` configuration is unnecessary\nas the default group has already initialized all fields and belongs to\nassociations for itself.\n\n**Fields**\n\nJust like in the list view, all fields are visible by default. If you specifically\ndeclare fields, only defined fields will be visible and they will be presented\nin the order defined. Thus both examples would render a form with\nonly one group (labeled \"Default group\") that would contain only one\nelement (labeled \"Title\").\n\nIn the list view label is the text displayed in the field's column header, but\nin the edit views label literally means the html label element associated with\nfield's input element.\n\nNaturally edit views' fields also have the visible option along with\nhide and show accessors as the list view has.\n\n**Fields - rendering**\n\nThe edit view's fields are rendered using partials. Each field type has its own\npartial per default, but that can be overridden:\n\n RailsAdmin.config do |config|\n config.model Team do\n edit do\n field :name do\n partial \"my_awesome_partial\"\n end\n end\n end\n end\n\nThe partial should be placed in your applications template folder, such as\n`app/views/rails_admin/main/_my_awesome_partial.html.erb`.\n\nOne can also completely override the rendering logic:\n\n RailsAdmin.config do |config|\n config.model Team do\n edit do\n field :name do\n render do\n bindings[:view].render :partial => partial.to_s, :locals => {:field => self}\n end\n end\n end\n end\n end\n\nThat example is just the default rendering method, but it shows you that you\nhave access to the current template's scope with bindings[:view]. There's also\nbindings[:object] available, which is the database record being edited.\nBindings concept was introduced earlier in this document and the\nfunctionality is the same.\n\n**Fields - overriding field type**\n\nIf you'd like to override the type of the field that gets instantiated, the\nfield method provides second parameter which is field type as a symbol. For\ninstance, if we have a column that's a text column in the database, but we'd\nlike to have it as a string type we could accomplish that like this:\n\n RailsAdmin.config do |config|\n config.model Team do\n edit do\n field :description, :string do\n # configuration here\n end\n end\n end\n end\n\nIf no configuration needs to take place the configuration block could have been\nleft out:\n\n RailsAdmin.config do |config|\n config.model Team do\n edit do\n field :description, :string\n end\n end\n end\n\nA word of warning, if you make field declarations for the same field a number\nof times with a type defining second argument in place, the type definition\nwill ditch the old field configuration and load a new field instance in place.\n\n**Fields - Available field types**\n\nRailsAdmin ships with the following field types:\n\n* belongs_to_association\n* boolean\n* date\n* datetime\n* decimal\n* file_upload _does not initialize automatically_\n* paperclip_file _initializes automatically if Paperclip is present_\n* float\n* has_and_belongs_to_many_association\n* has_many_association\n* has_one_association\n* integer\n* password _initializes if string type column's name is password_\n* string\n* text\n* time\n* timestamp\n* virtual _useful for displaying data that is calculated a runtime\n(for example a method call on model instance)_\n\n**Fields - Creating a custom field type**\n\nIf you have a reuseable field you can define a custom class extending\n`RailsAdmin::Config::Fields::Base` and register it for RailsAdmin:\n\n RailsAdmin::Config::Fields::Types::register(:my_awesome_type, MyAwesomeFieldClass)\n\nThen you can use your custom class in a field:\n\n RailsAdmin.config do |config|\n config.model Team do\n edit do\n field :name, :my_awesome_type do\n # configuration here\n end\n end\n end\n end\n\n**Fields - Creating a custom field factory**\n\nType guessing can be overridden by registering a custom field \"factory\", but\nfor now you need to study `lib/rails_admin/config/fields/factories/*` for\nexamples if you want to use that mechanism.\n\n### Mass Assignment Operations ###\n\n* Mass assign for every model configuration\n* Mass assign for every section (create, list, navigation and update)\n* Mass assign by field type\n\n**Mass assign for every model configuration**\n\nMass assignment operations are used to pass in configuration blocks for\nmultiple targets at once. For instance, the code below configures every models'\nlabel displayed uppercased in the list view.\n\n RailsAdmin.config do |config|\n config.models do\n list do\n label do\n label.upcase # in this context label refers to default label method\n end\n end\n end\n end\n\n**Mass assign for every section (create, list, navigation and update)**\n\nIf one would like to assign that same behavior for all the different views in\nRailsAdmin (create, list, navigation and update) one could pass the label\ndefinition one level higher:\n\n RailsAdmin.config do |config|\n config.models do\n label do\n label.upcase\n end\n end\n end\n\nNaturally this also works for a single model configuration:\n\n RailsAdmin.config do |config|\n config.model Team do\n label do\n label.upcase\n end\n end\n end\n\n**Mass assign by field type**\n\nOne can also assign configurations for all fields by type. For instance\nmodifying the date presentation of all datetime fields in all sections can be\naccomplished like this:\n\n RailsAdmin.config do |config|\n config.models do\n fields_of_type :datetime do\n strftime_format \"%Y-%m-%d\"\n end\n end\n end\n\nAuthorization\n-------------\n\nRails Admin has no specific authorization requirements so you can use\nwhichever authz framework best suits your needs.\n\n### Declarative Authorization\n\n[Declarative Authorization](https://github.com/stffn/declarative_authorization)\nworks well with Rails Admin. You need to hook\ndeclarative_authorization's code into Rails Admin's controllers and\nwrite appropriate authorization declarations.\n\nYou can hook declarative_authorization into Rails Admin using code\nlike this in an initializer (e.g., config/initializers/rails_admin.rb):\n\n require \"rails_admin/application_controller\"\n\n module RailsAdmin\n class ApplicationController < ::ApplicationController\n filter_access_to :all\n end\n end\n\nBy default, access to the controllers will be denied to all users, so\nyou need to write some authz rules so that the appropriate users can\nget access. These rules will vary, but here's an example:\n\n authorization do\n role :admin do\n has_permission_on :rails_admin_history, :to => :list\n has_permission_on :rails_admin_main, :to => [:index, :show, :new, :edit, :create, :update, :destroy, :list, :delete, :get_pages, :show_history]\n end\n end\n\nThis will allow the :admin role to do everything, and will prevent all\nother roles from doing anything.\n\nContributing\n------------\nIn the spirit of [free software](http://www.fsf.org/licensing/essays/free-sw.html), **everyone** is encouraged to help improve this project.\n\nHere are some ways *you* can contribute:\n\n* by using alpha, beta, and prerelease versions\n* by reporting bugs\n* by suggesting new features\n* by [translating to a new language](https://github.com/sferik/rails_admin/tree/master/config/locales)\n* by writing or editing documentation\n* by writing specifications\n* by writing code (**no patch is too small**: fix typos, add comments, clean up inconsistent whitespace)\n* by refactoring code\n* by resolving [issues](http://github.com/sferik/rails_admin/issues)\n* by reviewing patches\n\nSubmitting an Issue\n-------------------\nWe use the [GitHub issue tracker](http://github.com/sferik/rails_admin/issues) to track bugs and\nfeatures. Before submitting a bug report or feature request, check to make sure it hasn't already\nbeen submitted. You can indicate support for an existing issuse by voting it up. When submitting a\nbug report, please include a [Gist](http://gist.github.com/) that includes a stack trace and any\ndetails that may be necessary to reproduce the bug, including your gem version, Ruby version, and\noperating system. Ideally, a bug report should include a pull request with failing specs.\n\nSubmitting a Pull Request\n-------------------------\n1. Fork the project.\n2. Create a topic branch.\n3. Implement your feature or bug fix. *NOTE* - there's a small test app located in the spec/dummy_app directory that you can use to experiment with rails_admin.\n4. Add documentation for your feature or bug fix.\n5. Run `bundle exec rake doc:yard`. If your changes are not 100% documented, go back to step 4.\n6. Add specs for your feature or bug fix.\n7. Run `bundle exec rake spec`. If your changes are not 100% covered, go back to step 6.\n8. Commit and push your changes.\n9. Submit a pull request. Please do not include changes to the gemspec, version, or history file. (If you want to create your own version for some reason, please do so in a separate commit.)\n\nContact\n-------\nIf you have questions about contributing to RailsAdmin, please contact [Erik Michaels-Ober](http://github.com/sferik) and [Bogdan Gaza](http://github.com/hurrycane).\n","size":25325,"sha":"94616fa57520ac8147522c7cf9f03d555595c5ea","mode":"100644","mime_type":"text/plain"}}
|