I noticed that I can do a Model.find in a number of ways (assuming #user is an instance of the User model):
User.find(2)
=> #<User id: 2, name: "Mike Swift", email: "valid#email.com", ... etc ...
OR
User.find(#user)
=> #<User id: 2, name: "Mike Swift", email: "valid#email.com", ... etc ...
OR
User.find(#user[:id])
=> #<User id: 2, name: "Mike Swift", email: "valid#email.com", ... etc ...
OR
User.find(#user.id)
=> #<User id: 2, name: "Mike Swift", email: "valid#email.com", ... etc ...
Is there any real difference between the later three of these methods? (I already know User.find(n) would be the fastest) I would imagine they all work in about the same time, but perhaps I'm wrong.
In terms of sql they all do the same thing.
User.find(2)
This will be the fastest because there is no conversion needed.
Then User.find(#user.id) and User.find(#user[:id]).
And finally User.find(#user because rails needs convert the user to an ID.
User.find(2) should be faster as Rails doesn't have to do any work to figure out the id. The others require some level of message passing to get the id.
I doubt the difference is very significant though.
You could try all of them and look at your log to see how long it takes to get your response.
Related
I'm using Rails 5 and minitest. In minitest, how do I lookup an object from the database by one of its attributes (e.g. not the fixtures designation for the object). In my test I have
item = items(:one)
,,, do some db manipulation to this object ...
Item.all.each do |i|
puts "#{i.inspect}"
end
updated_item = Item.find(id: item.id)
But the line
updated_Item = Item.find(id: item.id)
dies with the error
ActiveRecord::RecordNotFound: Couldn't find Item with 'id'={:id=>980190962}
What is odd is taht in the lines above, where I print out the records in my database, I can see the object in question with the ID that Rails claims not to find ...
#<Item id: 298486374, name: "MyString", rating: 0, score: 0, created_at: "2018-01-19 20:25:05", updated_at: "2018-01-19 20:25:05">
#<Item id: 980190962, name: "Item1", rating: 1, score: 5, created_at: "2018-01-19 20:25:05", updated_at: "2018-01-19 20:25:05">
What am I doing wrong? How do I lookup the updated object?
find() looks by id , no need to tell, so:
updated_Item = Item.find(item.id)
I'm trying to display visitors' names in my rails admin show page.
I'm doing it this way:
field :visitors
But I get displayed the following:
Visitor #7 and Visitor #8
I've tried to do something like this with pretty value:
configure :visitors do
pretty_value do
bindings[:object].visitors.each do |visitor|
visitor.full_name
end
end
end
But it shows me objects' details:
[#<Visitor id: 7, first_name: "John", last_name: "Smith", created_at: "2016-03-03 10:23:34", updated_at: "2016-03-03 10:23:34", booking_id: 7>, #<Visitor id: 8, first_name: "Bob", last_name: "Smith", created_at: "2016-03-03 10:23:34", updated_at: "2016-03-03 10:23:34", booking_id: 7>]
I simply want to display something like this:
John Smith and Bob Smith
How can I do this?
Well, I've found the solution using map:
bindings[:object].visitors.all.map {|v| v.full_name}.join(', ')
In my application I have Posts that Users can create. When I initially started my project, I created some placeholder Posts and Users from the command line just so I can play around. As the application advanced I created a seed file and ran 'rake db:seed' from the command line. Everything worked fine but I realized that I still had the placeholder Posts and Users still in the database so I decided to delete them. I decided to destroy all Posts and Users from the command line using the 'destroy_all' method. I just wanted to see if it would work and it did as everything was deleted. But now when I run 'rake db:seed' to populate the database, nothing shows up. I get no errors and nothing gets returned when I run Post.all or User.all from the command line. I'm not sure what's going on but I would appreciate any assistance, thank you!
User.create(name: 'John', email: 'John#gmail.com', password: '123456', password_confirmation: '123456')
User.create(name: 'Bill', email: 'Bill#gmail.com', password: '123456', password_confirmation: '123456')
Post.create([
{
user_id: 1,
category_id: 1,
title: "Tech tattoos put a working circuit board on your skin",
url: "http://www.slashgear.com/tech-tattoos-put-a-working-circuit-board-on-your-skin-25416060/"
},
{
user_id: 2,
category_id: 1,
title: "This robot can print emoji on your fingernails",
url: "http://mashable.com/2015/11/24/nailbot-printed-manicure/#Rml2qXalMmqp"
},
{
user_id: 3,
category_id: 2,
title: "Thiago Silva scores a goal from behind the goal",
url: "http://www.gyfbin.com/2015/11/hgfp.gif.html"
}])
Have a simple way to you can see error message at. You can use bang (!) after create method (ex: User.create!(.....), Post.create!(.....)). Console will raise error message when have any errors.
If you do same that. you can search yourself error.
destroy_all doesn't drop the table. First you ran the seed file. so, 5 users were created with ID (1 to 5). It destroys the USERS but not truncate. Then you destroy those users. Again ran the seed file. Now the 5 users were created with ID (6 to 10). So, there is no user_id with 1 anymore. It may be the problem.
solution 1: You can drop the tables (user, post) and then migrate and seed.
solution 2:
pick user ids randomly. Use:
users = User.all.collect{|u| u.id}
# same goes for category.
Post.create([
{
user_id: users.sample,
category_id: 1,
title: "Tech tattoos put a working circuit board on your skin",
url: "http://www.slashgear.com/tech-tattoos-put-a-working-circuit-board-on-your-skin-25416060/"
},
{
user_id: users.sample,
category_id: 1,
title: "This robot can print emoji on your fingernails",
url: "http://mashable.com/2015/11/24/nailbot-printed-manicure/#Rml2qXalMmqp"
},
{
user_id: users.sample,
category_id: 2,
title: "Thiago Silva scores a goal from behind the goal",
url: "http://www.gyfbin.com/2015/11/hgfp.gif.html"
}])
Hope it helps!
Let's say I have this simple method in my helper that helps me to retrieve a client:
def current_client
#current_client ||= Client.where(:name => 'my_client_name').first
end
Now calling current_client returns this:
#<Client _id: 5062f7b851dbb2394a00000a, _type: nil, name: "my_client_name">
Perfect. The client has a few associated users, let's look at the last one:
> current_client.user.last
#<User _id: 5062f7f251dbb2394a00000e, _type: nil, name: "user_name">
Later in a new method I call this:
#new_user = current_client.user.build
And now, to my surprise, calling current_client.user.last returns
#<User _id: 50635e8751dbb2127c000001, _type: nil, name: nil>
but users count doesn't change. In other words - it doesn't add the new user but one user is missing... Why is this? How can I repair it?
current_client.users.count makes a round trip to the database to figure out how many user records are associated. Since the new user hasn't been saved yet (it's only been built) the database doesn't know about it.
current_client.users.length will give you the count using Ruby.
current_client.users.count # => 2
current_client.users.length # => 2
current_client.users.build
current_client.users.count # => 2
current_client.users.length # => 3
Don't mind me, I fricked up my attribute names :(
This is entirely possible, using the exact syntax I used - you just need to be able to spell!
I can't seem to get this to work, and it seems like a common enough scenario that there must be a solution, but I'm not having any luck with the correct terminology to get a helpful Google result.
I want to do this:
u = User.first
u.clients.find_or_create_by_email('example#example.com')
With the effect that a new Client is created with user_id = u.id.
Can I get the nice dynamic finders through a has_many relationship? If not, why?
Thanks :)
This
u = User.first
u.clients.find_or_create_by_email('example#example.com')
works if you have has_many relationship set. However, it won't raise validation error if you have any validations set on your Client object and it will silently fail if the validation fails.
You can check the output in your console when you do
u.clients.find_or_create_by_email('example#example.com') # => #<Client id: nil, email: 'example#example.com', name: nil, user_id: 1, another_attribute: nil, active: true, created_at: nil, updated_at: nil>
and the user_id will be set but not the id of client because the validation has failed and the client is not created
So this should create the client only if you pass all the required attributes of client object and the validation for client object has passed successfully.
So lets say your client model has validation on name as well apart from email then you should do
u.clients.find_or_create_by_email_and_name('example#example.com', 'my_name') #=> #<Client id: 1, email: 'example#example.com', name: 'my_name', user_id: 1, another_attribute: nil, active: true, created_at: "2009-12-14 11:08:23", updated_at: "2009-12-14 11:08:23">
This is entirely possible, using the exact syntax I used - you just need to be able to spell!