How to implement "top writers" table in Rails? - ruby-on-rails

In my Rails 3 application users can write messages/posts in forum.
I would like to display to users "Top Writes" table, something like:
Alex - 14% (i.e. 14% of forum's content was written by Alex)
Greg - 13%
Natalie - 10%
Rachel - 8%
...
Would you store the number of characters (probably excluding punctuation) in each message in a database along with other message details (and update it when message edited) ?
Would you store the number of characters that each user wrote along with other user details (and update this number once user adds / deletes / updates a message) ?
Would you store the total number of characters in the database (i.e. the sum of all numbers from 2. ?
Would you store the percentages that are going to be displayed (and update them accordingly) ?

I would focus on a metric that rewards good content, not just content. Stack Overflow is a good example of this --- you get rewarded when your peers value your content.
For your specific question:
Add columns on each Message: content-length
Add a column on each User: total-content-length
When you save a new message, recaculate total-content-length for the user (sum of all message.content-length)
The percentage based table at that point is fairly simple

Related

Google Datastudio show empty row combinations

I am creating a Google Data Studio report for a car dealership and I have a problem.
I have made these 3 screenshots to illustrate:
If you see on the first screenshot, the datasource is pretty simple, used/new indicates weather the car being sold is new or used and if it is a sportscar or family car, and exchange/clean deal indicates weather the dealership takes/buys the customers old car in for a trade off in price. The rest should be self explanatory.
On screenshot2-3 you see my report, I have one table for each salesperson and it shows the amount of sales for each combination that has sales.
The problem is this, I want the tables to show each combination even if it does not have any sales at all, it should just show 0 then in record count. Like Mike on the left has more combinations than john, I still want Johns table to show those combinations just with a 0 then, and it should be sorted the same on each table so they look the same, just different data in the cells.
Is this possible to do?
To solve this problem, you need to make a combination of data, from the database with itself. Your main analysis dimension, which will generate your combinations, is used/new and Exchange/Clean deal. So your combination should be:
The filter defined in the second database (right base) must contain a filter telling which person the table will be destined for. So, for each table, you must make a new combination that contains the person-specific filter.
I just took a sample from your original database (10 first lines) and the result is:

Is there a dimension modeling design pattern for multi-valued dimensions

I'm working on a data warehouse that seeks to capture website visits and purchase. We have a hypothesis that by identifying patterns from previous site visits you can get insights into visitor behavior for the current site visit
The grain of my fact table is individual website visits and we assign a 1 if the customer makes a purchase and a 0 if she does not. Our fact is additive. We would like to be able explore and understand how the actions of prior visits influence the action of the current visit so I'm trying to figure out how you would go about modeling this. On a particular site visit a visitor could have 1, 2 or 12 prior site visits.
So my question is how would I model a past visit dimension that includes the past visit date, past visit activity (purchase or no purchase, time on site, etc). Is this an example of a use for a bridge table.
A bridge table in a data-warehouse is primarily (exclusively?) for dealing with many to many relationships, which you don't appear to have.
If the grain of your fact table is website visits then you don't need a 'past visit' dimension, since your fact table contains the visit history already.
You have two dimensions here:
Customer
Date
Time on site is presumably a number, and since you are treating purchase/no purchase as a boolean score (1,0) these are both measures and belong in the fact table.
The Customer dimension is for your customer attributes. Don't put measures here (e.g. prior scores). You should also consider how to handle changes (probably SCD type 2).
You could put your date field directly in the fact table but it is more powerful as a separate dimension, since you can much more easily analyze by quarters, financial years, public holidays etc.
So,
Example Fact_Website_Visit table:
Fact_Website_Visit_Key | Dim_Customer_Key | Dim_Date_Key | Purchase(1,0) | Time_On_Site
Example Dim_Customer Dimension:
Dim_Customer_Key | Customer_ID | Customer_Demographic
Example Dim_Date Dimension:
Dim_Date_Key | Full_Date | IsWeekend
To demonstrate how this works I've written an example report to see sale success and average time spent online on weekends grouped by customer demographic:
SELECT
Dim_Customer.demographic,
COUNT(fact.Fact_Website_Visit_Key) AS [# of Visits],
SUM (fact.Purchase) AS [Total Purchases],
AVG (fact.Time_On_Site) AS [Average Minutes Online],
SUM (fact.Purchase)/COUNT(fact.Fact_Website_Visit_Key)*100 AS [% sale success]
FROM
Fact_Website_Visit fact
INNER JOIN Dim_Customer ON fact.Dim_Customer_Key=Dim_Customer.Dim_Customer_Key
INNER JOIN Dim_Date ON fact.Dim_Date_Key=Dim_Date.Dim_Date_Key
WHERE
Dim_Date.IsWeekend='Y'
GROUP BY
Dim_Customer.Demographic

UX Solution for Potential Activity Stream Spam

My app implements an activity stream for different types of activities. One of the activity types is related to the different virtual currency a user can accumulate. For example, a user can accumulate "Points" for posting a comment, voting on a topic, etc. If I were to do no filtering or aggregating, you would get a lot of self-generating spam over the course of a mere hour, for example:
Earned 5 points for commenting (total points = 505)
Earned 10 points for voting (total points = 515)
Earned 5 points for commenting (total points = 520)
Earned 5 points for commenting (total points = 525)
Earned 5 points for commenting (total points = 530)
Earned 10 points for voting (total points = 540)
Earned 10 points for voting (total points = 550)
Earned 10 points for voting (total points = 560)
...
...
...
How would you go about preventing this potential for self-generating spam but also present the stream of activities in such a way that invites your friends to see what you've been doing?
I can think of a couple options. The first being an aggregation of the data. I don't know how many activity types you have, but you could distill what you have posted down to 2 items:
<Name> made <x> comments and scored <x * 5> points!
<Name> voted on <x> things.
You could make each of these list items clickable to expand and show the details. So, after a click on the summary of comments user would see this:
<Name> made <x> comments and scored <x * 5> points!
Earned 5 points for commenting (total points = 505)
Earned 5 points for commenting (total points = 520)
Earned 5 points for commenting (total points = 525)
Earned 5 points for commenting (total points = 530)
<Name> voted on <x> things.
You could use something like jQuery UI accordion to implement this.
The approach Facebook takes is that it uses a sample post and then lets users know that more items are available, like this:
Earned 5 points for commenting (total points = 505)
Made <x> more comments
Then when the user clicks on the "Made <x> more comments" the user can see every comment (within a certain span of time).
Presuming you want to see in one glance if the user was recently active and how recent, I would propose something like the following:
I am not sure where you would want to show this, but maybe in the profile-page, or in the list of "friends". I would show an aggregation, that would show the most recent time-frame the user was active, and what she did:
E.g.
has just commented on
has made comments and votes in the last hour
has made comments and votes today
has made comments and votes this week
And you would only show the most recent of those. So if a user has just commented (within the last five minutes), show the first line. If she was active in the last hour, show the second line. And so on ...
This clearly shows the user was active and how long ago. I think that is the most important.
You could combine this with showing the total score, showing how active the user was overall.
Maybe something like:
<name>[<total_score>] has just commented on <x>
or
<name>[<total_score>] has made <x> comments and <y> votes in the last hour.
Mmmmmm i want the message to be shorter:
<name>[<total_score>] has earned <x> points in the last hour.
Is that clearer? Not sure.
This message would then be clickable, and that would link you to a pop-up chart/graph showing the activity (votes/comments/points) over the last week/month. A chart because it is very compact and very understandable.
What do you think?
I'd personally go with an alert like Stack Uses for instant notification of immediate activities. They quickly alert and then get out of the way. If you make them clickable, the user can drill down for detail if they like.
Then, somewhere like in an account section, I'd list all activities using jQuery DataTables, so they could be sorted, paged, filtered, and delivered via pipelined Ajax. Simple, efficient, and user friendly!
UI is about commonality, making a user feel comfortable in an environment they haven't already been by presenting familiar interactions. You'll see this same pattern used on sites like StackOverflow, Swagbucks, MyPoints, etc.

How to calculate user's info completeness in Rails

I have problem in my new rails project.I want to implement a function which can show the user's info completeness by a bar like Linkedin.
I think I can use a variable to record the completeness,but I don't have any idea about how to calculate it.
P.S I have two Model,one is the User Model,another is the Info Model.
This is, in fact, completely arbitrary. It's based entirely on which activities on the site you want to encourage.
A couple of mechanisms you can consider:
Model "accomplishments" with a completed/not completed status. Count up the ones you care about. Store the accomplishments based on activity either as they happen or at the end of the day in some batch job. For each user, calculate the percentage with the usual math (accomplishments completed/sum of available accomplishments) * 100 = percentage.
A variation of the same, but weighted based on what you consider more valuable contributions. In this case, the math is basically sum of (weight n * accomplishment n)/total weight.
The previous Careers.stackoverflow.com model made a geeky joke about Spinal Tap by making it possible to have counts greater than 100%. You can do that simply by undercounting the maximum accomplishments.

Quickbooks: Adding a negative value to an invoice using the QBDSK

Is there any way to add a line item containing a negative amount to an existing invoice?
I'm using QBSDK7 and QB Enterprise. (and if it matters .Net 3.5)
What we're attempting to do is automate the way we're creating invoices. We're already pulling in employee's time and applying it to the correct invoices, but when we go to add credits (just a negative amount on a line item on the invoice) using
InvoiceLineMod.Amount.SetValue(-1234)
it fails with the error "Transaction must be positive"
I've also tried adding a Service Item with a negative amount and giving it a positive quantity and I get the same result.
This seems like such a no-brainer as we have been doing this manually for the last 10 years. I'm guessing there is artificial restriction on this.
Some things to consider:
Credit Memos are no good as we need to display exact details of the reduction on the same page.
We don't have payments to apply yet in most cases.
This need to be done before any retainers are applied.
Any help would be greatly appreciated.
Can you show the complete code you're using to modify the invoice? Can you also show the exact error message you're getting?
It is possible, though to do you need to make sure that you're using a Discount Item as your ItemRef type (a Service Item will not work), and you need to make sure that the transaction as a whole is for a positive amount.
Sometimes our app has to adjust an invoice down with a negative number. I have been able to add negative line items using the following code. I have to set a quantity and a rate, instead of setting the amount.
IInvoiceLineAdd ila = ia.ORInvoiceLineAddList.Append().InvoiceLineAdd;
ila.ItemRef.ListID.SetValue(GetQBID(JobKey));
ila.Desc.SetValue("Adjustment");
ila.Quantity.SetValue(1);
ila.ORRatePriceLevel.Rate.SetValue(-1.00);
Quickbooks doesn't allow you to post an invoice with a negative balance. If you try to do it through the UI, it prompts you to create a credit memo instead. (And vice-versa if you try it with a credit memo.)
You can enter negative quantities and/or prices into the line items, but the total of the invoice has to be >= 0 or it won't post (i.e., add other line items that offset the negative amounts).
The solution is to use credit memos. Your client-side processing will be more complicated, but it's the only choice with Quickbooks.

Resources