rails find_by_name getting wrong result - ruby-on-rails-2

I'm working on a rails 2 project. I'm trying to fetch a record from tags table by using find_by_* . Its giving different result.
May I know why is this working like this?
In my model:
existing = user.tags.find_by_name(tag)
in Log:
SELECT * FROM `tags` WHERE (`tags`.`name` = 'Ror') AND (`tags`.user_id = 1) LIMIT 1
RuntimeError (#<Tag id: 980191043, user_id: 1, name: "rOr", created_at: "2014-09-09 12:18:55", updated_at: "2014-09-09 12:18:55">):

Are you using MySQL?
If so it is likely it is doing a case insensitive comparison. Whether MySQL is case sensitive is based around the field collation of the column: http://dev.mysql.com/doc/refman/5.0/en/charset-column.html

Related

Modify response structure using Eloquent: API Resources

I am newbie in Laravel. I am using laravel as a REST End Point, I use Eloquent: API Resources for transforming my data to JSON.
I am using Collection and Resource to parse my data came from my query. So below is the structure of my response:
data:
0
id
name
1
id
name
Now I need to have some categorization in the data, hence I require the data structure to be in below format
data:
24H
0
id
name
1
id
name
7D
0
id
name
1
id
name
I tried couple of ways to accomplish this, the static way I tried for testing was to change the ResourceCollection's toArray method and append the key 24H for the data we get.
But I know that is not correct and generic way.
I would like to know how I can achieve the above response format in generic and extensible manner.
Your help is much appreciated.
Thanks.
Laravel Collections have a groupBy method that may help you here, make sure the column you want to use as the key is selected as well. So if you have
data:
0:
id: 1
name: Bob
category: 24H
1:
id: 2
name: Bill
category: 7D
Then $data->groupBy('category') would return the following
data:
24H:
0:
id: 1
name: Bob
category: 24H
7D:
0:
id: 2
name: Bill
category: 7D

Formatting ActiveRecord results for parsing?

I have a database with entries which I can fetch using ActiveRecord. Currently, using something like post.to_yaml yields:
!ruby/object:Post
concise_attributes:
- !ruby/object:ActiveModel::Attribute::FromDatabase
name: id
value_before_type_cast: 1
- !ruby/object:ActiveModel::Attribute::FromDatabase
name: user
value_before_type_cast: efy5qC5YmJNml23JowOUrlmfN0D2
- !ruby/object:ActiveModel::Attribute::FromDatabase
name: content
value_before_type_cast: bol4
- !ruby/object:ActiveModel::Attribute::FromDatabase
name: location
value_before_type_cast: '123'
- !ruby/object:ActiveModel::Attribute::FromDatabase
name: timestamp
value_before_type_cast: '12:00'
new_record: false
The exact collection i'm returning is as follow: record = Post.order(:timestamp).offset(15 * 0).first(15)
This returned result contains several fields which will be returned to a Flutter application. The data will populate a widget with several fields such as content, date and location, all of which is returned by the above query.
I could use a Dart library to parse the YAML, but is there a better way to condense the returned values so that only the necessary fields are shown?
As per the description shared it seems like you have data from the database and you now need to select only particular fields that needs to be shown.
As per current scenario you could use something like:
post.as_json(only: [:content, :name, :location])
Else you could modify the query you are using by using select statement for selecting specific attributes from database.
Post.select(:name, :content, :location)
Hope it helps!!

rails 5 enum where "like"

I'm trying to query an activerecord model enum and use the like operator in the where method, and it just doesnt work. Is there some trick to allow me to query an enum this way? Works fine on regular columns. Here it is in the console.
Regular string column (title) works as shown below
irb(main):092:0> Proposal.select(:id,:department,:status).where('title like "test%"')
Proposal Load (0.3ms) SELECT "proposals"."id", "proposals"."department", "proposals"."status" FROM "proposals" WHERE (title like "test%") LIMIT ? [["LIMIT", 11]]
=> #<ActiveRecord::Relation [#<Proposal id: 7, department: 1, status: "In Progress">, #<Proposal id: 61, department: 2, status: "Won">]>
However, trying it on an enum, gives no results.
irb(main):094:0> Proposal.select(:department,:status).where('status like "Wo%"')
Proposal Load (0.3ms) SELECT "proposals"."department", "proposals"."status" FROM "proposals" WHERE (status like "Wo%") LIMIT ? [["LIMIT", 11]]
=> #<ActiveRecord::Relation []>
Any idea why I can't use like operator on enum? I'm trying to use this to filter a view with datatables.net server side processing.
Enum stores data as integer like 0,1,2,3... Then rails map number to enum value defined in model. That is the reason why you doesn't get result

Trying to generate a Random String to Save to PG Table as client_number Rails 4, PGSQL

I am trying to generate a "Client Number" automatically when an admin generates a new client in our Rails 4 app.
I have read several articles on this but most are talking about breakable tokens.
so far my Client model only has a client_number attribute and it is a string.
my model looks like:
class Client < ActiveRecord::Base
before_save generate_client_number
validates_uniqueness_of :client_number
def generate_client_number
self.client_number = SecureRandom.hex(2).upcase
end
end
We are using PostgreSQL as our DB, I am relatively new to rails. after adding the above to our model, it errors out in the console this is the error it throws:
NameError: undefined local variable or method `generate_client_number' for #<Class:0x007fc59bdd7008>
Did you mean? generated_attribute_methods
I am a little bit lost as to where I am going wrong here. any assistance would be greatly appreciated, I am sure this is an oversight on my part. Thanks in advance.
EDIT #1:
The error has been eliminated by fixing the code error. And Adding
before_save :generate_client_number
however when I attempt to Create the random string and save to db I now get:
irb(main):013:0> Client.create
(0.1ms) BEGIN
Client Exists (0.2ms) SELECT 1 AS one FROM "clients" WHERE "clients"."client_number" IS NULL LIMIT 1
(0.1ms) ROLLBACK
=> #<Client id: nil, client_number: nil, created_at: nil, updated_at: nil>
It's just a matter of using a symbol correctly:
before_save :generate_client_number
These after_* and before_* hooks are defined by a symbol with the name of the method called, so you need to write :generate_client_number, with :, instead of just generate_client_number.
About the fact it is not generating a number, your error message implies your are getting a duplicate and having a roolback. I suggest you to try
self.client_number = SecureRandom.uuid.upcase
Ill add my own answer here as well as I have resolved this issue,
It appears that the first time I attempted to create a Client it saved a record containing a nil ID, how or why I don't know.. however blowing out the client records and starting from scratch has resolved my issue. Thanks for your input.

group method for activerecord. Docs are confusing?

I don't get what this means in the Rails tutorial:
group(*args) public
Allows to specify a group attribute:
User.group(:name)
=> SELECT "users".* FROM "users" GROUP BY name
Returns an array with distinct records based on the group attribute:
User.group(:name) [User id: 3, name: "Foo", ...>, #User id: 2, name: "Oscar", ...>]
I don't see the grouping with the example they gave...
Group is most useful (I think) if you are trying to count stuff in your database or if you join multiple tables. Let me give a few examples.
1.
If you want to know how many users there are in your data base with each name then you can do:
User.group(:name).count
this will return a hash looking something like this:
{ ann: 4, bert: 15, cecilia: 3 ... }
I do not know why there are so many Berts in your database but anyway...
2.
If your users have related records (for instance cars) the you can use this to get the first car included in your activerecord model (the reason it will be the first is because of how group works and is further explained in the link below)
User.joins(:cars).select('users.*, cars.model as car_model, cars.name as car_name').group('users.id')
Now all records in this result will have a method called car_model and one called car_name.
You can count how many cars each user has with one single query.
User.joins(:cars).select('users.*, count(cars.id) as car_count').group('users.id')
Now all records will have a car_count.
For further reading: Mysql group tutorial
Hope this shed enough light over groups for you to try them out a little bit. I do not think you can fully understand them until you worked with them a little bit.

Resources