Skip to content

Instantly share code, notes, and snippets.

@mahm
Last active August 29, 2015 14:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mahm/f40999f0e8daf4990937 to your computer and use it in GitHub Desktop.
Save mahm/f40999f0e8daf4990937 to your computer and use it in GitHub Desktop.
AngularJS & Rails
class Api::BaseController < ApplicationController
include CheckCSRFForAngular
end
class Api::TasksController < Api::BaseController
inherit_resources
respond_to :json
defaults route_prefix: 'api'
custom_actions resource: [:done]
before_action :authenticate_user!
def done
resource.done
render json: resource, status: :ok
end
private
def permitted_params
params.permit(task: [:name])
end
def begin_of_association_chain
current_user
end
end
//= require jquery
//= require jquery_ujs
//= require angular
//= require angular-resource
//= require angular-ui-router
//= require angular-bootstrap
//= require lodash
//= require app/tasks/tasks
//= require app/tasks/tasks.service
//= require app/tasks/tasks.controller
class ApplicationController < ActionController::Base
# Prevent CSRF attacks by raising an exception.
# For APIs, you may want to use :null_session instead.
protect_from_forgery with: :exception
end
{
"vendor": {
"name": "bower-rails generated vendor assets",
"dependencies": {
"angular" : "latest",
"angular-resource" : "latest",
"angular-ui-router" : "latest",
"angular-bootstrap" : "latest",
"lodash" : "latest"
}
}
}
# ref: http://stackoverflow.com/questions/14734243/rails-csrf-protection-angular-js-protect-from-forgery-makes-me-to-log-out-on
module CheckCSRFForAngular
extend ActiveSupport::Concern
included do
after_filter :set_csrf_token_to_cookie
end
private
def set_csrf_token_to_cookie
cookies['XSRF-TOKEN'] = form_authenticity_token if protect_against_forgery?
end
def verified_request?
super || form_authenticity_token == request.headers['X-XSRF-TOKEN']
end
end
source 'https://rubygems.org'
gem 'rails', '4.1.7'
gem 'pg', group: :production
gem 'rails_12factor', group: :production
gem 'uglifier', '>= 1.3.0'
gem 'jbuilder', '~> 2.0'
gem 'enumerize'
gem 'inherited_resources'
gem 'has_scope'
gem 'devise'
# css
gem 'sass-rails', '~> 4.0.3'
gem 'bootstrap-sass'
gem 'font-awesome-rails'
gem 'compass-rails'
# javascripts
gem 'bower-rails', '~> 0.9.1'
gem 'coffee-rails', '~> 4.0.0'
gem 'jquery-rails'
group :development do
gem 'spring'
gem 'quiet_assets'
end
group :development, :test do
gem 'sqlite3'
end
<div class="col-md-12">
<div ng-app="todoApp" ui-view="">
</div>
</div>
Rails.application.routes.draw do
namespace :api, defaults: { format: :json } do
resources :tasks do
post :done
end
end
devise_for :users
root to: 'tasks#index'
end
class Task < ActiveRecord::Base
belongs_to :user
def done
self.done_at = if done_at
nil
else
DateTime.now
end
save!
end
end
'use strict';
angular.module('todoApp')
.controller('TasksController', ['$scope', 'Task', function($scope, Task){
$scope.tasks = Task.query();
$scope.done = function (task) {
Task.done({id: task.id}, function (_task) {
task.done_at = _task.done_at;
});
};
$scope.add = function () {
Task.save($scope.task, function (_task) {
$scope.tasks.push(_task);
$scope.task.name = null;
});
};
$scope.remove = function ($event, task) {
$event.stopPropagation();
Task.remove({id: task.id}, function () {
$scope.tasks = _.filter($scope.tasks, function (_t) {
return _t.id != task.id;
});
});
};
$scope.hover = function (task) {
return task.showDelete = !task.showDelete;
};
}])
;
<div class="row">
<div class="col-md-8 col-md-offset-2">
<!-- Add Todo -->
<form ng-submit="add()" style="margin-bottom: 12px">
<div class="input-group">
<input class="form-control" type="text" ng-model="task.name" />
<div class="input-group-btn"><button class="btn btn-default" type="submit"><i class="fa fa-plus"></i></button></div>
</div>
</form>
<!--Todo List -->
<div class="panel panel-info">
<div class="panel-heading">
やらなきゃいけないリスト
</div>
<ul class="list-group">
<li class="list-group-item task-item" ng-repeat="task in tasks | orderBy: ['done_at', 'created_at']" ng-mouseenter="hover(task)" ng-mouseleave="hover(task)" ng-click="done(task)">
<div ng-class="{ done: task.done_at }">{{task.name}}</div>
<div ng-show="task.showDelete" style="float: right; margin-top: -25px;">
<button class="btn btn-danger btn-sm" ng-click="remove($event, task)"><i class="fa fa-trash-o"></i></button>
</div>
</li>
</ul>
</div>
</div>
</div>
'use strict';
angular.module('todoApp', [
'ngResource',
'ui.router',
'ui.bootstrap'
])
.config(['$stateProvider', '$urlRouterProvider', function ($stateProvider, $urlRouterProvider) {
$urlRouterProvider
.otherwise('/');
$stateProvider
.state('tasks', {
url: '/',
templateUrl: '<%= asset_path 'app/tasks/tasks.html' %>',
controller: 'TasksController'
})
;
}])
;
'use strict';
angular.module('todoApp')
.provider('Task', function () {
this.$get = ['$resource', function ($resource){
var Task = $resource('/api/tasks/:id', { id: '@id' }, {
done: { method: 'POST', url: '/api/tasks/:id/done' }
}
);
Task.prototype = {
};
return Task;
}];
});
class TasksController < ApplicationController
before_action :authenticate_user!
def index
end
end
class User < ActiveRecord::Base
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable, :omniauthable, :recoverable, :rememberable
devise :database_authenticatable, :trackable, :validatable
has_many :tasks, dependent: :destroy
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment