Permalink
Browse files

Add the ability to create arbitrary links in the project bar.

GitHaven's primary purpose is to be a way to manage Git repositories.

Code hosting websites often include other tools for managing projects
not directly related to code hosting such as:
- Wiki
- Issue Tracker
- Code Review
- Mailing lists

With the ability to add external links repositories users
don't have to wait for GitHaven to include tools*, they can link
to existing tools today.

*Tools that might be crummy like sourceforge's issue tracker or
tools that GitHaven will never get around to including.
  • Loading branch information...
1 parent 785d8e1 commit aa908eaea0238c4a6cfd0068a096ae6cbf90b2b1 @icefox committed Apr 5, 2010
@@ -0,0 +1,102 @@
+class LinksController < ApplicationController
+ before_filter :require_login
+
+ # GET /links/new
+ # GET /links/new.xml
+ def new
+ repo = params[:repo];
+ if !repo
+ flash[:notice] = t('repository.notfound')
+ redirect_to root_url
+ return
+ end
+
+ @repository = Repository.find(params[:repo])
+ return if !require_authorization
+
+ @link = Link.new
+ @link.repository = @repository
+
+ respond_to do |format|
+ format.html # new.html.erb
+ format.xml { render :xml => @link }
+ end
+ end
+
+ # POST /links
+ # POST /links.xml
+ def create
+ @link = Link.new(params[:link])
+
+ @repository = @link.repository
+ return if !require_authorization
+ @repository.links << @link
+
+ respond_to do |format|
+ if @link.save
+ flash[:notice] = 'Link was successfully created.'
+ format.html { redirect_to(edit_repository_url(@repository)) }
+ format.xml { render :xml => @link, :status => :created, :location => @links }
+ else
+ format.html { render :action => "new" }
+ format.xml { render :xml => @link.errors, :status => :unprocessable_entity }
+ end
+ end
+ end
+
+ # GET /links/1/edit
+ def edit
+ @link = Link.find(params[:id])
+ @repository = @link.repository
+ return if !require_authorization
+ end
+
+ # PUT /link/1
+ # PUT /link/1.xml
+ def update
+ @link = Link.find(params[:id])
+ @repository = @link.repository
+ return if !require_authorization
+
+ respond_to do |format|
+ if @link.update_attributes(params[:link])
+ flash[:notice] = 'Link was successfully updated.'
+ format.html { redirect_to(edit_repository_url(@repository)) }
+ format.xml { head :ok }
+ else
+ format.html { render :action => "edit" }
+ format.xml { render :xml => @link.errors, :status => :unprocessable_entity }
+ end
+ end
+ end
+
+ # DELETE /link/1
+ # DELETE /link/1.xml
+ def destroy
+ @link = Link.find(params[:id])
+ @repository = @link.repository
+ return if !require_authorization
+
+ @link.destroy
+
+ respond_to do |format|
+ format.html { redirect_to(edit_repository_url(@repository)) }
+ format.xml { head :ok }
+ end
+ end
+
+private
+ def require_authorization
+ if !@repository
+ flash[:notice] = t('repository.notfound')
+ redirect_to root_url
+ return false
+ end
+ if @repository.user != @loggedinuser
+ flash[:notice] = t('repository.notowner')
+ redirect_to(edit_repository_url(@repository))
+ return false
+ end
+ return true
+ end
+end
@@ -0,0 +1,2 @@
+module LinksHelper
+end
View
@@ -0,0 +1,6 @@
+class Link < ActiveRecord::Base
+ belongs_to :repository
+ validates_uniqueness_of :name, :scope => :repository_id
+ validates_presence_of :name
+ validates_presence_of :url
+end
@@ -4,6 +4,7 @@ class Repository < ActiveRecord::Base
belongs_to :user
has_many :permissions, :dependent => :destroy
has_many :tags, :dependent => :destroy
+ has_many :links, :dependent => :destroy
validates_presence_of :name
validates_uniqueness_of :name, :scope => :user_id
@@ -0,0 +1,18 @@
+<%= page_heading "Edit Link" %>
+<h1>Edit link for <%= link_to h(@repository.name), edit_repository_path(@repository) %></h1>
+
+<% form_for(@link) do |f| %>
+ <%= f.error_messages %>
+ <%= f.hidden_field(:repository_id) %>
+ <p>
+ <%= f.label :name %><br />
+ <%= f.text_field :name %>
+ </p>
+ <p>
+ <%= f.label :url %><br />
+ <%= f.text_field :url %>
+ </p>
+ <p>
+ <%= f.submit "Update" %>
+ </p>
+<% end %>
@@ -0,0 +1,18 @@
+<%= page_heading "New Link" %>
+<h1>New link for <%= link_to h(@repository.name), edit_repository_path(@repository) %></h1>
+
+<% form_for(@link) do |f| %>
+ <%= f.error_messages %>
+ <%= f.hidden_field(:repository_id) %>
+ <p>
+ <%= f.label :name %><br />
+ <%= f.text_field :name %>
+ </p>
+ <p>
+ <%= f.label :url %><br />
+ <%= f.text_field :url %>
+ </p>
+ <p>
+ <%= f.submit "Add" %>
+ </p>
+<% end %>
@@ -35,6 +35,9 @@
<ul>
<li><%= link_to 'Source', :action => 'show', :branch => @branch %></li>
<li><%= link_to 'Commits', :controller => 'repositories', :action => 'commits', :repo => @repository.name, :user => @repository.user.username, :branch => @branch %></li>
+ <% @repository.links.each { |l| %>
+ <li><a target="_blank" href="<%= l.url %>"><%= l.name %></a>
+ <% } %>
<% if @owner == @loggedinuser -%><li id="repository_admin"><%= link_to 'Admin', edit_repository_path(@repository) %></li><% end %>
</ul>
</div>
@@ -36,6 +36,19 @@
</ul>
<%= button_to 'Add another tag', { :controller => 'tags', :action => 'new', :repo => @repository.id}, :method => :get %>
+<hr>
+<h2>External Links</h2>
+<ul>
+<% for link in @repository.links %>
+<li>
+<%= h link.name %>
+<%= h link.url %>
+<%= link_to '(Edit)', { :controller => 'links', :action => 'edit', :id => link.id } %>
+<%= link_to '(Remove)', link, :confirm => 'Are you sure?', :method => :delete %>
+<% end %>
+</ul>
+<%= button_to 'Add another link', { :controller => 'links', :action => 'new', :repo => @repository.id}, :method => :get %>
+
<hr>
<h2>Repository Permissions</h2>
View
@@ -1,4 +1,5 @@
ActionController::Routing::Routes.draw do |map|
+
# Root
map.root :controller => 'application'
@@ -18,12 +19,17 @@
:controller => 'tags',
:conditions => { :method => :get }
+ map.connect 'links/new/:repo',
+ :controller => 'links',
+ :action => 'new'
+
# RESTful Routes
map.resources :users
map.resources :sshkeys
map.resources :repositories
map.resources :permissions
map.resources :tags
+ map.resources :links
map.connect 'permissions/:action/:repo',
:controller => 'permissions',
@@ -99,6 +105,6 @@
:conditions => { :method => :get }
# Default Routes
- #map.connect ':controller/:action/:id'
- #map.connect ':controller/:action/:id.:format'
+ map.connect ':controller/:action/:id'
+ map.connect ':controller/:action/:id.:format'
end
@@ -0,0 +1,15 @@
+class CreateLinks < ActiveRecord::Migration
+ def self.up
+ create_table :links do |t|
+ t.integer :repository_id
+ t.string :name
+ t.string :url
+
+ t.timestamps
+ end
+ end
+
+ def self.down
+ drop_table :links
+ end
+end
View
@@ -9,7 +9,15 @@
#
# It's strongly recommended to check this file into your version control system.
-ActiveRecord::Schema.define(:version => 20100331023518) do
+ActiveRecord::Schema.define(:version => 20100405021755) do
+
+ create_table "links", :force => true do |t|
+ t.integer "repository_id"
+ t.string "name"
+ t.string "url"
+ t.datetime "created_at"
+ t.datetime "updated_at"
+ end
create_table "permissions", :force => true do |t|
t.integer "repository_id", :null => false
@@ -0,0 +1,11 @@
+# Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html
+
+one:
+ repository_id: 1
+ name: MyString
+ url: MyString
+
+two:
+ repository_id: 1
+ name: MyString
+ url: MyString
@@ -0,0 +1,45 @@
+require 'test_helper'
+
+class LinksControllerTest < ActionController::TestCase
+ test "should get index" do
+ get :index
+ assert_response :success
+ assert_not_nil assigns(:links)
+ end
+
+ test "should get new" do
+ get :new
+ assert_response :success
+ end
+
+ test "should create links" do
+ assert_difference('Links.count') do
+ post :create, :links => { }
+ end
+
+ assert_redirected_to links_path(assigns(:links))
+ end
+
+ test "should show links" do
+ get :show, :id => links(:one).id
+ assert_response :success
+ end
+
+ test "should get edit" do
+ get :edit, :id => links(:one).id
+ assert_response :success
+ end
+
+ test "should update links" do
+ put :update, :id => links(:one).id, :links => { }
+ assert_redirected_to links_path(assigns(:links))
+ end
+
+ test "should destroy links" do
+ assert_difference('Links.count', -1) do
+ delete :destroy, :id => links(:one).id
+ end
+
+ assert_redirected_to links_path
+ end
+end
@@ -0,0 +1,8 @@
+require 'test_helper'
+
+class LinkTest < ActiveSupport::TestCase
+ # Replace this with your real tests.
+ test "the truth" do
+ assert true
+ end
+end

0 comments on commit aa908ea

Please sign in to comment.