I'm just trying to increment a record by 1 starting at 2000, when a new record is created upon clicking on the create action to create a record:
if resource_model == Student then #resource.testing_id = id + 2000 end
So if the record has an id of 1, I assume that the testing_id will be 2001. But instead it returns:
2147483647 (maximum mysql limit?)
Any suggestions on how to address this? Thanks.
You can't know record ID during create. ID is known after saving record do database.
You can't relay on ID to give you values like 1, 2, 3 ... and so on.
Don't store value like ID+2000, becouse you can get it at any time by calculating id+2000.
You can get next testing_id by something like this:
if resource_model == Student then
#resource.testing_id = Student.first(:order => "testing_id DESC").testing_id + 1
end
But if two processes at the same time will fetch the same value then you will have duplicate testing_id.
Object.idf is a (deprecated) method that returns the Ruby object ID, which uniquely identifies the object. Rails has overridden id so that in models it refers to the database primary key. I'm going to take a guess that your code snippet is from a controller, and that's why id is returning a strange and large number: It's the Ruby object id of the controller, not the primary key of the object. Give id a receiver, e.g. #resource.id, and see how that works.
2147483647 = 2 ^(32-1)
Could you show some of your code here?
From what i'm guessing here is that you are comparing apples with strawberries :P.
I think you are adding a "1" on a string so that means for example:
2000 + 1 = 20001
20001 + 1 = 200001
So if you do that a couple of times this means you will get to the maximum size of an int (21475483647). I don't know this for a 100% sure, but this has to do with the way you ask your question and the way you don't post code etc...
I hope this edit was helpfull tho.
Related
Let's imagine if that I have 5 User records in the db, one of those 5 records is a user with age attribute 30.
And that I want to find or create two users with age attribute 28 and 30.
If I do this :
User.where(age: [28, 30])
This will give me a single user which has age 30, but it won't give me back the user with age 28 (doesn't exist).
Or if I do this
User.where(age: 28).where(age: 30)
There is no record with both ages present. Let's imagine age is just an arbitrary attribute, and the age value is an arbitrary value which can be anything.
How would I get all the records based on certain attributes/values combination and if they don't exist yet, create them?
You can actually use a range on the where conditions:
User.where(age: (28..30))
This will work for finding. To create a new user with the age of missing values I believe you will need to code it by hand.
If you want a range, you can just put a raw SQL statement in the where clause, like this:
User.where("age >= 28 AND age <= 30")
If you want a specific set of ages, you can use a list in the where clause:
unless User.where("age IN (28,30)").length > 0
# Code to create user with the age you want
end
Finally, there's also the first_or_initialize and first_or_create methods, which can be joined to where clauses. If no record is found from the where search, one is initialized/created.
User.where("age IN (28,30)").first_or_initialize
Rails 4 has a similar find_or_create_by method.
I have a database field called sample_code. This field is composed on the following way: sample_id/year/lab_id
The lab_id is fixed, always the same. The year changes accordingly to the current year... The sample_id its incremental (resetting every year and not a database field).
What I want to do is every-time I create a new sample it generates this sample_code for me and saves it along with the rest of the sample fields...
My doubts are:
1 - How can I keep incrementing sample_id if it's not on the database?
2 - How can I reset the sample ID code each year?
3 - Where's the best place to put/call this code? Sample's controller?
Thanks for all the help you can give
If you're not using your database outside of your app, it should be fine to just store the sample_id as its own column. You can then put a method on your model that returns something like:
def sample_code
"#{sample_id}/#{Time.now.year}/<lab_id>"
end
Then you can just increment sample_id each time.
EDIT
Since you need to reset the id to 1 each year and the model is called Sample, you should avoid confusion by calling it something like annual_id instead of sample_id. sample_id would likely be confused with sample.id, which is a completely different thing.
With that change, you should just store the info in three columns on the model to make it easy: annual_id, year, and lab_id. Then for each record you can set:
annual_id = Sample.where(year: Time.now.year).pluck(:annual_id).max.to_i + 1
year = Time.now.year
lab_id = <however you are defining this>
This will use the current year for year and then reset the annual_id to 1 when there are no records because the year has changed (new year will give nil.to_i + 1 => 1).
Then you can just return the format you want for any given data point:
def sample_code
"#{annual_id}/#{year}/#{lab_id}"
end
I want to build functionality in my Rails application that shows follower trends over time.
Currently, my following methodology involves creating and destroying relationship objects - following creates an object with the IDs of the follower and followed and unfollowing deletes that relationship object.
Since the relationship object is deleted upon an unfollow, it's impossible to go back and look at how many followers existed for a followed at any given time.
To solve this, the best solution I can think of is this:
Instead of deleting a relationship object upon unfollowing, create a new object with a negative value of, say, -1. Following would create an object with a positive value of +1. Therefore, adding up the total values for a given pair would yield whether or not they were currently following (1 or 0), while historical trends could also be calculated by adding up the total following values for a given followed.
My question is: Is this the most elegant solution this problem? Is there an easier way to do it? I realize that it's possible to use cron jobs to output a daily number, but that seems like it would duplicate data. Any other suggestions?
Any help would be greatly appreciated!
I would add an active field then instead of deleting the relationship record I would set the record to inactive. Then you'll have to update all of your user facing queries to reflect active = 1. Then you can use the records with active = 0 for reporting purposes. You can also add a deactivated_at field that stores the date that the record was deactivated.
An example scenario would be user 1 follows user 2, follows user 3, follows user 4, un-follows user 2, re-follows user 2, un-follows user 4.
follower_id followed_id active created_at deactivated_at
1 2 0 9/10/2012 9/13/2012
1 3 1 9/10/2012 NULL
1 4 0 9/10/2012 9/17/2012
1 2 1 9/16/2012 NULL
just use paranoia
https://github.com/radar/paranoia
class Relationship < ActiveRecord::Base
acts_as_paranoid
...
end
(if you have a unique index over the two numeric ID columns, remove it, use a plain index)
Then you can have
def currently_following_count(uid)
Relationship.where(:followed_id => uid).count
end
def historical_following_count(uid)
Relationship.unscoped.where(:followed_id => uid).count
end
I want to check by an unique ID whether a record is already created. If it is, I want to add 1 to the amount attribute. If it is not, I want to create it and set the amount attribute to 1.
I already have this: ##have = current_user.haves.create_or_update_by_id(params[:have]) but I'm not quite sure how I would set the amount right.
Thanks
Use ActiveRecord's increment method (Documentation):
#have = current_user.haves.find_or_initialize_by_id(params[:have])
#have.increment(:amount)
#have.save
It initializes amount attribute to zero if nil and adds the value passed as by (default is 1). If not nil, it just increment the attribute value.
I would probably split this into two operations.
#have = current_user.haves.find_or_initialize_by_id(params[:have]) do |h|
h.amount = 0
end
#have.amount += 1
#have.save
The first statemnt will find the record by its unique ID or initialize a new record with the provided ID and amount set to 0. The block is only run on initialize, not on find. Then we increment the amount no matter what the state was originally and save the record back to the db.
Is there anyway for me to identify whether an object/record is dirty before saving and which fields are changed in Rails?
Example
Suppose I have a Person model and Person has a property called name and age. In the db, Person with id 1 is named "John" with age 20.
p = Person.find 1
p.name #John
p.age #20
now, when I change his name from John to Nathan, is there any way for me to identify
the the object is changed (dirty)
and which fields got changed
Now I know the answer for the first one. If I change his name to Nathna, I can do the following
p.name = "Nathan"
p.changed? #true
However, is there anyway for me to identify which field was changed? May be a method that returns an array of fields that got changed?
p.dirty_fields #[:name]
See http://api.rubyonrails.org/classes/ActiveModel/Dirty.html#method-i-changes, specifically changed.