Conflicts: app/models/layer.rb app/views/layers/show.html.haml config/routes.rb db/schema.rbmaster
| @@ -0,0 +1,3 @@ | |||||
| # Place all the behaviors and hooks related to the matching controller here. | |||||
| # All this logic will automatically be available in application.js. | |||||
| # You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/ | |||||
| @@ -41,37 +41,7 @@ class FeedsController < ApplicationController | |||||
| @feed = Feed.find(params[:id]) | @feed = Feed.find(params[:id]) | ||||
| end | end | ||||
| # POST /feeds | |||||
| # POST /feeds.json | |||||
| def create | |||||
| Rails.logger.debug "Feed URL: %s" % params['feed']['feed_url'] | |||||
| if Feed.where(:feed_url => params['feed']['feed_url']).size == 1 # ensure this test returns the values we expect | |||||
| Rails.logger.debug "Adding existing feed to a new layer" | |||||
| @feed = Feed.where(:feed_url => params['feed']['feed_url']).first | |||||
| @layer = Layer.find(params['feed']['new_layer_id']) # assumes that the specified layer exists | |||||
| # Attach the existing feed to the specified layer (making sure we only add each one once) | |||||
| @feed.layers << @layer unless @feed.layers.include?(@layer) | |||||
| else | |||||
| # Create a new feed | |||||
| Rails.logger.debug "Creating a new feed" | |||||
| @feed = Feed.new(params[:feed]) | |||||
| @layer = Layer.find(params['feed']['new_layer_id']) # assumes that the specified layer exists | |||||
| @feed.layers << @layer unless @feed.layers.include?(@layer) | |||||
| end | |||||
| respond_to do |format| | |||||
| if @feed.save | |||||
| format.html { redirect_to @layer, notice: 'Feed added OK' } | |||||
| format.json { render json: @feed, status: :created, location: @feed } | |||||
| else | |||||
| format.html { render action: "new" } | |||||
| format.json { render json: @feed.errors, status: :unprocessable_entity } | |||||
| end | |||||
| end | |||||
| end | |||||
| # Feeds are created through the Subscriptions controller | |||||
| # PUT /feeds/1 | # PUT /feeds/1 | ||||
| # PUT /feeds/1.json | # PUT /feeds/1.json | ||||
| @@ -16,8 +16,7 @@ class LayersController < ApplicationController | |||||
| # GET /layers/1.json | # GET /layers/1.json | ||||
| def show | def show | ||||
| @layer = Layer.find(params[:id]) | @layer = Layer.find(params[:id]) | ||||
| @feed = Feed.new | |||||
| @feed.new_layer_id = @layer.id | |||||
| @subscription = Subscription.new(:layer_id => @layer.id) | |||||
| respond_to do |format| | respond_to do |format| | ||||
| format.html # show.html.erb | format.html # show.html.erb | ||||
| @@ -0,0 +1,46 @@ | |||||
| class SubscriptionsController < ApplicationController | |||||
| def create | |||||
| Rails.logger.debug "Feed URL: %s" % params['subscription']['feed_url'] | |||||
| if Feed.where(:feed_url => params['subscription']['feed_url']).size == 1 # ensure this test returns the values we expect | |||||
| Rails.logger.debug "Adding existing feed to a new layer" | |||||
| @feed = Feed.where(:feed_url => params['subscription']['feed_url']).first | |||||
| @layer = Layer.find(params['subscription']['layer_id']) # assumes that the specified layer exists | |||||
| # Attach the existing feed to the specified layer (making sure we only add each one once) | |||||
| # @feed.layers << @layer unless @feed.layers.include?(@layer) | |||||
| else | |||||
| # Create a new feed | |||||
| Rails.logger.debug "Creating a new feed" | |||||
| @feed = Feed.create(:feed_url => params[:subscription][:feed_url]) | |||||
| @layer = Layer.find(params['subscription']['layer_id']) # assumes that the specified layer exists | |||||
| # @feed.layers << @layer unless @feed.layers.include?(@layer) | |||||
| end | |||||
| @subscription = Subscription.new(:feed => @feed, :layer => @layer) | |||||
| begin | |||||
| respond_to do |format| | |||||
| if @subscription.save | |||||
| format.html { redirect_to @layer, notice: 'Feed added OK' } | |||||
| format.json { render json: @feed, status: :created, location: @feed } | |||||
| else | |||||
| format.html { render action: "new" } | |||||
| format.json { render json: @feed.errors, status: :unprocessable_entity } | |||||
| end | |||||
| end | |||||
| rescue ActiveRecord::RecordNotUnique | |||||
| redirect_to @layer, alert: 'That feed is already on this layer' | |||||
| end | |||||
| end | |||||
| def destroy | |||||
| @subscription = Subscription.find(params[:id]) | |||||
| @layer = @subscription.layer | |||||
| @subscription.destroy | |||||
| respond_to do |format| | |||||
| format.html { redirect_to @layer, notice: 'Subscription deleted OK' } | |||||
| format.json { head :no_content } | |||||
| end | |||||
| end | |||||
| end | |||||
| @@ -0,0 +1,2 @@ | |||||
| module SubscriptionsHelper | |||||
| end | |||||
| @@ -1,6 +1,7 @@ | |||||
| class Feed < ActiveRecord::Base | class Feed < ActiveRecord::Base | ||||
| has_many :posts, :dependent => :destroy | has_many :posts, :dependent => :destroy | ||||
| has_and_belongs_to_many :layers | |||||
| has_many :subscriptions | |||||
| has_many :layers, :through => :subscriptions, :uniq => true | |||||
| attr_accessible :title, :url, :description, :generator, :last_fetched, :feed_url | attr_accessible :title, :url, :description, :generator, :last_fetched, :feed_url | ||||
| attr_accessor :new_layer_id # non model attribute used when creating new feeds from within a layer | attr_accessor :new_layer_id # non model attribute used when creating new feeds from within a layer | ||||
| @@ -1,6 +1,8 @@ | |||||
| class Layer < ActiveRecord::Base | class Layer < ActiveRecord::Base | ||||
| has_many :subscriptions | |||||
| has_many :feeds, :through => :subscriptions, :uniq => true | |||||
| attr_accessible :name | attr_accessible :name | ||||
| has_and_belongs_to_many :feeds | |||||
| # Unique name for Layar layer | # Unique name for Layar layer | ||||
| def layar_name | def layar_name | ||||
| @@ -0,0 +1,5 @@ | |||||
| class Subscription < ActiveRecord::Base | |||||
| attr_accessor :feed_url | |||||
| belongs_to :feed | |||||
| belongs_to :layer | |||||
| end | |||||
| @@ -8,17 +8,8 @@ | |||||
| - @feed.errors.full_messages.each do |msg| | - @feed.errors.full_messages.each do |msg| | ||||
| %li= msg | %li= msg | ||||
| .field | |||||
| -# | |||||
| = f.label :title | |||||
| = f.text_field :title | |||||
| .field | .field | ||||
| = f.label "URL" | = f.label "URL" | ||||
| = f.text_field :feed_url, :size => 120 | = f.text_field :feed_url, :size => 120 | ||||
| = f.hidden_field :new_layer_id, :value => @feed.new_layer_id | |||||
| = f.submit 'Save', :id => 'submit' | = f.submit 'Save', :id => 'submit' | ||||
| -# | |||||
| .field | |||||
| = f.label :last_fetched | |||||
| = f.datetime_select :last_fetched | |||||
| .actions | .actions | ||||
| @@ -12,7 +12,7 @@ | |||||
| %h2 Feeds | %h2 Feeds | ||||
| #new_feed | #new_feed | ||||
| = render 'feeds/form' | |||||
| = render 'subscriptions/form' | |||||
| %p= link_to "Fetch all", :fetch_all, :class => "button" | %p= link_to "Fetch all", :fetch_all, :class => "button" | ||||
| @@ -25,21 +25,21 @@ | |||||
| %th | %th | ||||
| %th | %th | ||||
| - @layer_posts = 0 | - @layer_posts = 0 | ||||
| - @layer.feeds.each do |f| | |||||
| - @layer_posts += f.posts.count | |||||
| - @layer.subscriptions.each do |s| | |||||
| - @layer_posts += s.feed.posts.count | |||||
| %tr | %tr | ||||
| %td | %td | ||||
| .feed_title | .feed_title | ||||
| = link_to f.title, f | |||||
| %td.right= f.posts.count | |||||
| = link_to s.feed.title, s.feed | |||||
| %td.right= s.feed.posts.count | |||||
| %td | %td | ||||
| - if f.last_fetched.nil? | |||||
| - if s.feed.last_fetched.nil? | |||||
| never | never | ||||
| - else | - else | ||||
| = (time_ago_in_words(f.last_fetched) + " ago").gsub(/ +/, " ").html_safe | |||||
| %td= link_to "Fetch", fetch_feed_url(f), :class => "button" | |||||
| %td= link_to 'Edit', edit_feed_path(f), :class => "button" | |||||
| %td= link_to 'Delete', delete_feed_layer_path(:feed_id => f.id), :confirm => "Delete #{f.title} from this layer?", :method => :delete, :class => "button" | |||||
| = (time_ago_in_words(s.feed.last_fetched) + " ago").gsub(/ +/, " ").html_safe | |||||
| %td= link_to "Fetch", fetch_feed_url(s.feed), :class => "button" | |||||
| %td= link_to 'Edit', edit_feed_path(s.feed), :class => "button" | |||||
| %td= link_to 'Delete', s, :confirm => "Delete #{s.feed.title}?", :method => :delete, :class => "button" | |||||
| %tr | %tr | ||||
| %td | %td | ||||
| @@ -0,0 +1,16 @@ | |||||
| = form_for @subscription do |f| | |||||
| %h2 Add a feed | |||||
| -if @subscription.errors.any? | |||||
| #error_explanation | |||||
| %h2= "#{pluralize(@subscription.errors.count, "error")} prohibited this feed from being saved:" | |||||
| %ul | |||||
| - @subscription.errors.full_messages.each do |msg| | |||||
| %li= msg | |||||
| .field | |||||
| = f.label "URL" | |||||
| = f.text_field :feed_url, :size => 120 | |||||
| = f.hidden_field :layer_id, :value => @subscription.layer.id | |||||
| = f.submit 'Save', :id => 'submit' | |||||
| .actions | |||||
| @@ -75,6 +75,7 @@ module Apollo | |||||
| # http://mongomapper.com/documentation/getting-started/rails.html | # http://mongomapper.com/documentation/getting-started/rails.html | ||||
| config.generators do |g| | config.generators do |g| | ||||
| g.template_engine :haml | g.template_engine :haml | ||||
| g.stylesheets false | |||||
| end | end | ||||
| # Time.zone = 'London' | # Time.zone = 'London' | ||||
| end | end | ||||
| @@ -11,10 +11,11 @@ Apollo::Application.routes.draw do | |||||
| resources :users | resources :users | ||||
| resources :sessions | resources :sessions | ||||
| resources :password_resets | resources :password_resets | ||||
| resources :subscriptions | |||||
| get "posts/near" | get "posts/near" | ||||
| resources :feeds, :except => :destroy do | |||||
| resources :feeds, :except => [ :create, :destroy ] do | |||||
| member do | member do | ||||
| get 'fetch' | get 'fetch' | ||||
| end | end | ||||
| @@ -0,0 +1,7 @@ | |||||
| class ConvertFeedsLayersTableToSubscriptions < ActiveRecord::Migration | |||||
| def change | |||||
| rename_table :feeds_layers, :subscriptions | |||||
| add_column :subscriptions, :id, :primary_key | |||||
| add_index :subscriptions, :id, :name => "id" | |||||
| end | |||||
| end | |||||
| @@ -0,0 +1,5 @@ | |||||
| class AddTimestampsToSubscriptions < ActiveRecord::Migration | |||||
| def change | |||||
| add_timestamps :subscriptions | |||||
| end | |||||
| end | |||||
| @@ -11,7 +11,7 @@ | |||||
| # | # | ||||
| # It's strongly recommended to check this file into your version control system. | # It's strongly recommended to check this file into your version control system. | ||||
| ActiveRecord::Schema.define(:version => 20130328153610) do | |||||
| ActiveRecord::Schema.define(:version => 20130408142010) do | |||||
| create_table "delayed_jobs", :force => true do |t| | create_table "delayed_jobs", :force => true do |t| | ||||
| t.integer "priority", :default => 0 | t.integer "priority", :default => 0 | ||||
| @@ -40,13 +40,6 @@ ActiveRecord::Schema.define(:version => 20130328153610) do | |||||
| t.datetime "last_fetched" | t.datetime "last_fetched" | ||||
| end | end | ||||
| create_table "feeds_layers", :id => false, :force => true do |t| | |||||
| t.integer "feed_id" | |||||
| t.integer "layer_id" | |||||
| end | |||||
| add_index "feeds_layers", ["feed_id", "layer_id"], :name => "index_feeds_layers_on_feed_id_and_layer_id", :unique => true | |||||
| create_table "layers", :force => true do |t| | create_table "layers", :force => true do |t| | ||||
| t.string "name" | t.string "name" | ||||
| t.datetime "created_at", :null => false | t.datetime "created_at", :null => false | ||||
| @@ -68,6 +61,16 @@ ActiveRecord::Schema.define(:version => 20130328153610) do | |||||
| t.datetime "published" | t.datetime "published" | ||||
| end | end | ||||
| create_table "subscriptions", :force => true do |t| | |||||
| t.integer "feed_id" | |||||
| t.integer "layer_id" | |||||
| t.datetime "created_at" | |||||
| t.datetime "updated_at" | |||||
| end | |||||
| add_index "subscriptions", ["feed_id", "layer_id"], :name => "index_feeds_layers_on_feed_id_and_layer_id", :unique => true | |||||
| add_index "subscriptions", ["id"], :name => "id" | |||||
| create_table "users", :force => true do |t| | create_table "users", :force => true do |t| | ||||
| t.string "email" | t.string "email" | ||||
| t.string "crypted_password" | t.string "crypted_password" | ||||
| @@ -0,0 +1,11 @@ | |||||
| # Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/Fixtures.html | |||||
| # This model initially had no columns defined. If you add columns to the | |||||
| # model remove the '{}' from the fixture names and add the columns immediately | |||||
| # below each fixture, per the syntax in the comments below | |||||
| # | |||||
| one: {} | |||||
| # column: value | |||||
| # | |||||
| two: {} | |||||
| # column: value | |||||
| @@ -0,0 +1,7 @@ | |||||
| require 'test_helper' | |||||
| class SubscriptionsControllerTest < ActionController::TestCase | |||||
| # test "the truth" do | |||||
| # assert true | |||||
| # end | |||||
| end | |||||
| @@ -0,0 +1,4 @@ | |||||
| require 'test_helper' | |||||
| class SubscriptionsHelperTest < ActionView::TestCase | |||||
| end | |||||
| @@ -0,0 +1,7 @@ | |||||
| require 'test_helper' | |||||
| class SubscriptionTest < ActiveSupport::TestCase | |||||
| # test "the truth" do | |||||
| # assert true | |||||
| # end | |||||
| end | |||||