Where in Rails to fill in gaps in time series? - ruby-on-rails

My basic set of models looks roughly like this (simplified):
[ PayPeriod ]
id
start_date
end_date
notes
[ Transaction ]
id
amount
fkPayPeriod
When a user logs in, I want to present them with a list of the last 4 pay periods. The user can select a pay period to enter notes and transactions.
I'm inclined to just do something like this in the controller:
def index
#pay_periods = PayPeriod.get_or_create_last(4)
end
The PayPeriod model itself would implement the behavior, and records would be created "on demand" as users used the app.
An alternative approach might be to have some other (background) process that combs through accounts on a daily basis to proactively create new PayPeriods. Although neither solution strikes me as particularly challenging, I'd like to get some feedback on where others feel this functionality belongs conceptually.

I'd say it depends on what a PayPeriod is, conceptually. Is it a universal description of time periods on a common calendar (i.e., the year 2011 has 26 pay periods of two weeks each)? If so, then the creation of all the PayPeriods belongs in your db/seeds.rb file.
If a PayPeriod belongs to an account, I'd say that the creation of the last four PayPeriods belongs in an after_create hook on the account in question. Going forward from there, I think the best practice would be to create new PayPeriods as your user needs them; that is, the first time I go to add notes or a transaction to a PayPeriod is probably when it should get created.
If for any reason you have a system policy in place that allows users to edit a specific window of PayPeriods (e.g., you can edit this and the next calendar year), then you might set up a Rake task and hook it up to a Cron job that runs it however often it needs to be run (e.g., if you're limiting your window by calendar year, then you could set up a Cron job to run every January 1 at 12:01am that creates the year's PayPeriods).

Related

How to Manage Time/Date Schedules?

I'm putting together a tool that allows a user to generate reports for a class of students. I'd like to incorporate report "periods" or "schedules" but I'm unsure of how to do so.
Essentially, I want the user to assign an evaluation "schedule" to each class, i.e. from the 5th of one month to the 4th of the next. Thus, reports will (and must) be run for sequential periods. However, I do want the user to be able to adjust the end period of the schedule for a student on an ad hoc basis.
I thought of creating a "schedules" table, but I'm not sure of how to store the start and end dates so the cycle can be repeated. Anyone have any suggestions?
I've used ice_cube (GitHub project) with some success. The module handles recurrences well, it's got its own serializer/deserializer, and it's well-documented.
You could create a report model/table with a start day and end day (such as 4 and 5) and use that to set the date with. This would persist to the database normally, but for a one off report that doesn't need to be stored, you could just create a new report with a different end date.
I.E., you have a reports table for persistent reports (A report for an entire class of students), but don't save your individual reports.

What is best practice for handling application configuration?

I'll phrase the question in the context of my application but I think it does have a wider scope generally for configuration. My application allows companies to track absences and holidays for its employees. One of the benefits is that it will automatically increase a person's holiday entitlement based on rules set by the employer. The intention is for the company to choose between:
A) automatically increase an employee's entitlement by a set number of days every year e.g. on 1 January each year, holiday entitlement increases by 1 day; or
B) an employee's entitlement increases based on length of service e.g. after 2 years' employment, entitlement increases by 2 days
What is the best way to implement this functionality? The first option is fairly simple to implement as I have track the start/end dates of each leave year and the increment for each employee can be stored as an integer.
I guess I'm looking for best practice solutions to store the chosen method; how to store the relevant options and all in an extensible format allowing me to add further methods later.
I'm working with Ruby on Rails but the question is probably relevant to other languages.
Thanks
Robin
What about: Store the balance in Employee. Employee belongs to Company. When the time comes, set the balance by using something like
self.company.set_balance(self.balance)
So your employee assessor runs over all the employees and asks the company to recalculate its balance.
If it's a global policy, then you don't need to tell Company who the employee is, but if you needed to have special cases, you could pass the Employee to the set_balance method so that it would have more information about the employee being recalculated.
As for the Compay's strategy in how to increase the days, I'd put it in a model to limit the code changes needed if the strategy is changed.
If it's a simple rule, maybe just keep it in a key/value pair:
"holiday_entitlement"/"flat"
or
"holiday_entitlement"/"length of service"
I would not keep the the values (1 or 2) in the DB in order to avoid smart employees hacking into the DB and putting 'favourable' values in there :)

Creating a Calendar/Planner Application - Ruby on Rails

I am considering developing an application using Ruby on Rails that is a planner of sorts. I would like to give a user the ability to see a list of days, click a particular day, and then add things like: Meals, Expenses, Events, Todos, and Exercises. Really I am doing this for me and my growing family.
I am curious with how best to implement this. I can certainly see that Meals, Expenses, etc. need to belong_to :user but I am curious how to implement the belongs_to :day or something like that. Using the created_at or updated_at wouldn't necessarily allow me to provide views for future dates.
I can see how if I created a Days table and then added days through a time and date field that this would work but seems a little strange to ask people to create the actual days.
Or perhaps instead of that I could just create links to variables that search for #today, #tomorrow, but that would get messy.
I have browsed for gems/plugins but can't find one that works. Ideally a person would be able.
Anyone have any thoughts on how to implement something like this?
There are a number of existing Rails calendars, such as http://github.com/elevation/event_calendar or http://github.com/topfunky/calendar%5Fhelper.
However, to answer your specific question about dates: I don't think there's any need to have Day as a model; simply give each event a start date and time, and an end date and time. Remember that Ruby makes it easy to search based on ranges, so "give me all of the events next week" is a cinch if each event has dates and times associated with it.
I'll give it a shot...
Two tables; users and events. A user has many events and an event belongs to a user. Meal, Expenses, etc. are various types of Event. Within events, you can have fields for start and end time of the events. If needed (lets say an events last over multiple days), you could remove the day/time when events occurs into it's own table.
This way, when displaying the calendar for a user, you can find all the events for that date. If none are found, then display nothing.
What do you think?
I would add a model called "Events" and have a properties of the model to represent start date/time, end date/time. I do not think you need a Days model, you can generate your calendar view from the Date class built into ruby.
I have done same kind of project for the Event management in training institute. At there I used event_calender plug in with rails. (enter link description here)
In there we just need to create Event model only. Then we can easily work with that.

Keeping the history of model associations

I have multiple models that need to have their history kept pretty much indefinitely or at least a very long time. The application I would keep track of daily attendance statistics for people in different organizations, and a couple of other similar associations. I've realized that I can't ever delete users due to the user not showing up in a query for attendance anytime before said user was deleted. The problem I'm having is finding a nice way of keep track of old associations as well as querying on those old associations.
If I have a connecting table between Users and Organizations, I could just add a new row with the new associations between a User and the Organization the user belongs to, and query on the old ones based on the date, but I really don't have any elegant way of doing this, everything just feels ugly. I was just wondering if anyone has dealt with anything like this before, and maybe had a solution they had already implemented. Thanks.
From a modeling point, the relationship sounds like the one between Employee and Employer, namely Employment. This would hold a reference to both Employee and Employer along with some notion of the TimePeriod (ie, startDate and end Date). If you wanted to query 'active' employees then they are all the ones with a startDate <= Now() && endDate >= Now(), 'terminated' employees have endDate < Now(), etc.
I can't tell in your case what the relationship is between Users and Organizations, and what makes the relationship start and end, but a concept similar to Employment, Membership, Enrollment or Contract is likely there. When you say daily attendance, is it not daily over a period of time? The time period is the basis for your queries.
Hope that helps,
Berryl
Create an is_deleted field so that you can still query those "deleted" users, but modify your code so that they will behave everywhere else as if they are deleted. Then you never need to actually delete the row and lose data.
There are a number of plugins that keep track of revisions to models, including their associations. Take a look at this search for revision-related plugins.

Freezing associated objects

Does anyone know of any method in Rails by which an associated object may be frozen. The problem I am having is that I have an order model with many line items which in turn belong to a product or service. When the order is paid for, I need to freeze the details of the ordered items so that when the price is changed, the order's totals are preserved.
I worked on an online purchase system before. What you want to do is have an Order class and a LineItem class. LineItems store product details like price, quantity, and maybe some other information you need to keep for records. It's more complicated but it's the only way I know to lock in the details.
An Order is simply made up of LineItems and probably contains shipping and billing addresses. The total price of the Order can be calculated by adding up the LineItems.
Basically, you freeze the data before the person makes the purchase. When they are added to an order, the data is frozen because LineItems duplicate nessacary product information. This way when a product is removed from your system, you can still make sense of old orders.
You may want to look at a rails plugin call 'AASM' (formerly, acts as state machine) to handle the state of an order.
Edit: AASM can be found here http://github.com/rubyist/aasm/tree/master
A few options:
1) Add a version number to your model. At the day job we do course scheduling. A particular course might be updated occasionally but, for business rule reasons, its important to know what it looked like on the day you signed up. Add :version_number to model and find_latest_course(course_id), alter code as appropriate, stir a bit. In this case you don't "edit" models so much as you do a new save of the new, updated version. (Then, obviously, your LineItems carry a item_id and an item_version_number.)
This generic pattern can be extended to cover, shudder, audit trails.
2) Copy data into LineItem objects at LineItem creation time. Just because you can slap has_a on anything, doesn't mean you should. If a 'LineItem' is supposed to hold a constant record of one item which appeared on an invoice, then make the LineItem hold a constant record of one item which appeared on an invoice. You can then update InventoryItem#current_price at will without affecting your previously saved LineItems.
3) If you're lazy, just freeze the price on the order object. Not really much to recommend this but, hey, it works in a pinch. You're probably just delaying the day of reckoning though.
"I ordered from you 6 months ago and now am doing my taxes. Why won't your bookstore show me half of the books I ordered? What do you mean their IDs were purged when you stopped selling them?! I need to know which I can get deductions for!"
Shouldn't the prices already be frozen when the items are added to the order? Say I put a widget into my shopping basket thinking it costs $1 and by the time I'm at the register, it costs $5 because you changed the price.
Back to your problem: I don't think it's a language issue, but a functional one. Instead of associating the prices with items, you need to copy the prices. If every item in the order has it's own version of a price, future price changes won't effect it, you can add discounts, etc.
Actually, to be clean you need to add versioning to your prices. When an item's price changes, you don't overwrite the price, you add a newer version. The line items in your order will still be associated with the old price.

Resources