Creating a User Time Sheet for a RoR Web App - ruby-on-rails

I'm kind of a newb to RoR and I'm working on creating my first web app.
So...My question is, how do I create a user time sheet in RoR?
What I need to do is create a classroom time sheet for students' (Users) reading times at home.
The students (Users) are able to sign up and have a profile created. From there, I would like for them to have access to log in their reading time(s).
I have attached examples of just some simple timesheets that would work perfectly for this.
I just do not know where to start and have not been able to find any gems that could help me create this.
Time Sheet 1
TimeSheet 2

Users: Ruby part
Use Devise gem - it will save a lot of time for you.
Add Devise to user model (something like that: rails generate devise User), then autogenerate basic Devise pages (sign in, sign up, etc), see Devise tutorials:
https://launchschool.com/blog/how-to-use-devise-in-rails-for-authentication
http://guides.railsgirls.com/devise
Also you'll probably need something like Job model with fields user_id, time_spent, date or something.
Timesheets: JS part
Time tracking is more front-end part of work, so you'll need to write some JS scripts for time tracking, which will monitor user activity and then send it to Job mobel on Rails side.
Track time spent on page (example):
var page_opened;
$(document).ready(function () {
page_opened = Date.getTime();
$(window).unload(function () {
page_closed = Date.getTime();
$.ajax({
url: "/save_user_time",
data: {
'timeSpent': page_closed - page_opened,
'job_id': job_id
}
})
});
}
Also you defenetly should take a look on some basic Rails tutorials for better understanding:
http://guides.rubyonrails.org/getting_started.html
https://www.codecademy.com/learn/learn-rails

Related

Pass id to new create form (but not through URL) - rails

I used the following advice to set up new_invoice_path in my app:
https://stackoverflow.com/a/14570788
How can I (using the outlined scenario in the question/answer I linked to above) make it so that when a user clicks a link to create a new invoice for a specific account the account_id passes to the form but does not show up in the URL?
I view the current solution (pass account_id to form via URL) as problematic because...
Someone could easily modify the URL and start creating invoices in different accounts.
It looks sloppy (especially if you start trying to pass things other than just account_id)

Cache data from external api with rails or ember?

I have an ember/rails application with three main templates, Home, Contacts, and Payments. Both the contacts and payments templates need an array of contacts. This array needs to be populated from an external api. Currently, for the contacts every time I am going to this template the external api is being hit. Ideally I would like to hit the api asynchronously when a user first signs in, grabs this data once and can refer back to it without hitting the external api until necessary.
With rails I could easily just add has_one :contacts_list for user with a postgres json column and when switching the templates conditionally refresh this whenever needed. I am curious as to the best way to deal with this problem in ember.
You should create a DS.Model for 'contact' and use a has_many on Contacts and Payments model. Then, you could specify 'async: true' like
DS.hasMany('contact', {async: true}),
This will load the contacts asynchronously if they have not been loaded already. If they have been loaded, it will simply return the loaded contacts.
I am assuming that you have the following models: Contacts, Payments.
I've used the setupController method on a route to do this type of caching. Just check to see if the content is already available, and only load it if it's not there. Something like this:
App.ContactsRoute = Ember.Route.extend({
setupController : function(controller,model){
if(!controller.get('content')){
this.store.find('contact').then(function(contacts){
controller.set('content',contacts)
});
}
}
});

Ember.js session cookie based authentication with Rails and devise

I'm looking to satisfy 3 goals with my Ember.js app authentication using rails, devise and a cookie based session.
Redirected to #/sessions/new if they're not logged in.
Always show the current user's information in the application template.
If the user is logged in and they go to #/some/route directly. The current user should be loaded on load.
I've watched these embercast videos: Client-side Authentication Part 1 & Client-side Authentication Part 2. They're a little out of date but helpful.
But still can't full solution. Anyone have full Rails 4, Devise, Emberjs 1.0.0 example?
Biggest problem is having a strategy to load the current user on page load and setting the current user when the sign in form is submitted.
Right now this is my strategy:
App.User = Em.Object.extend();
App.User.reopenClass({
current: function() {
return Ember.$.getJSON("/users/current").then(function(data) {
return data
})
}
});
App.ApplicationRoute = Ember.Route.extend({
model: function() {
return App.User.current();
}
});
App.SessionsNewController = Ember.ObjectController.extend({
actions: {
save: function(data) {
var self = this, data = this.getProperties('email', 'password');
$.post("/sessions", { session: data }).always(function(response, status, data) {
if (status == "success") {
self.transitionToRoute('index');
} else {
self.set('errorMessage', data);
}
})
},
}
});
I would not say this is not doable. But you will do lots of extra and unnecessary works to get the authentication working, which can all be done with a simple page redirect.
I've collected some opinions from Derick, the author of Backbone.Marionette. Though these are for Backbone but not Ember.js, the situation of client side authentication is same.
I find it painful and unnecessary to try and make Backbone/Marionette handle the authentication and re-loading of the authorized site stuff. Once they log in, redirect them to a different URL that the server handles, and have the server send down all the stuff that they need, as an authenticated user. https://stackoverflow.com/a/18151935
Another quote from Derick as well:
Right. And there’s a lot of cases where I just flat out say, “Do not do single-page applications,” as well. And a login screen is the biggest example of that. In all of the clients that I’ve had in the last couple of years, they’ve all asked me, “Hey, I’m having this problem. I’m trying to get my login screen to give me the current user information back from the server and redo all of this stuff on the screen without refreshing everything.” My answer every single time is, “Don’t do that." http://javascriptjabber.com/056-jsj-marionette-js-with-derick-bailey/
Also think about other cases, say Gmail. You won't get a smooth transition after click "Sign in" button on Gmail's sign in page. There will be redirect with rather big data loading as well :)
From users' perspective, they won't say Gmail is not great just because there is a redirect after signing in. After all signing/sign up is much much less frequent than daily mail operations.
So my suggestion is, reload all resources after user session changed. Let Rails and Devise do these dirty jobs in traditional fashion.

Handling user registration in an Ember.js/Rails/Devise app

I'm playing around with writing a pure Ember.js app on top of Rails 4 and I'm puzzled how user management is handled. My original idea was to use pure server-rendered templates (ERB) to do the user registration and login via Devise, and then the rest of the app would use the Ember framework.
The problem with that is that Ember wants to take over the <body> tag and control the entire viewport. In this way I can't pick and choose which aspects of the app should use server-rendered Erb templates and which should live in the Ember logic.
I see plenty of examples of how to deal with a user that's already logged-in and ember-auth looks interesting to facilitate authentication-aware controllers, but I've seen no tutorials or suggestions on allowing the full user signup experience to take place in the Ember app.
Am I missing something, either from a technical perspective where I just haven't found the right code or from a architectural perspective where I shouldn't be doing it this way?
This is with ember-rails (0.12.0 w/1.0.0.rc3.3 ember-source), Rails 4.0.0.rc1, and Devise (rails4 branch).
ember-auth dev here.
You don't actually need any special treatment for user sign up. Treat user sign up as you would for another model, in the sense that creating a user model will not require authentication. (Editing it or deleting it should require authentication though.)
Your implementation might look like:
App.User = DS.Model.extend
email: DS.attr 'string'
password: DS.attr 'string'
App.UsersNewRoute = Em.Route.extend
model: ->
App.User.createRecord()
App.UsersNewController = Em.ObjectController.extend
create: ->
#store.commit()
Error-checking, template code, etc, skipped for brevity.
This is here for reference to what worked based off of #heartsentwined's answer since pasting in comments doesn't work very well. See the comments for more info. Since my api returns the user json I just pass in the format its expecting.
didCreate: function() {
var user = App.Auth.get('_response').response.user;
var auth = {auth_token: user.auth_token, id: user.id};
App.Auth.get('_response').canonicalize(auth);
App.Auth.trigger('signInSuccess');
}
UPDATE:
I switched to ember-model and now do this in the same place that I call model.save() (the submit action of SignupController).
var model = this.get('model');
model.on('didCreateRecord', function() {
var user = this.data;
var auth = {auth_token: user.auth_token, user_id: user.id, remember_token: user.remember_token};
App.Auth.get('_response').canonicalize(auth);
App.Auth.trigger('signInSuccess');
});
model.save();
The solutions above ALMOST but not quite worked for me. Here is what did work:
didCreate: function() {
var user = App.Auth.get('_response').response.user;
App.Auth.signIn({
data: {
'email': user.email,
'password': this.get('password'),
'remember': true
}
});
}
App.Auth.signIn is used in the documentation explicitly: http://ember-auth.herokuapp.com/docs

Rails 3 & MailChimp - Speeding things up

Currently I have a Rails 3 app that subscribes new users up to MailChimp. As part of my user model, I have this:
after_create :add_user_to_mailchimp
before_destroy :remove_user_from_mailchimp
before_save :update_mailchimp_values
Then, each of those three actions are some variation on this:
def add_user_to_mailchimp
mailchimp = Hominid::API.new(MAILCHIMP_API_KEY)
list_id = mailchimp.find_list_id_by_name MAILCHIMP_LIST_NAME
info = { }
mailchimp.list_subscribe(list_id, self.email, info, 'html', false, true, false, false))
end
The problem is that this is slowing down the registration process... It can take 3 or 4 seconds to return, and I'm worried that once the floodgates open on the site (later today, probably), it'll be ridiculously out of hand.
Is there an easy way to make this faster, or do I need to set up something like delayed_job?
Because you're relying on the response time of their API then it would be best to use delayed_job to handle the processing that way you can return focus back to the user and the site - this equally applies when sending emails etc which need to establish a connection to a third party.

Resources