Rails console output to recreate objects - ruby-on-rails

I accidentally deleted 1000 objects from a database and now trying to recreate these objects. Thankfully I was able to scroll through my console output and find the records. I copy and pasted the console output which is in this (greatly shortened) format:
[#<Assignment id: 276503, school_id: 2091, listing_id: 251572, created_at: "2018-08-30 05:02:36", updated_at: "2018-08-30 05:02:36">, #<Assignment id: 279532, school_id: 1233, listing_id: 252702, created_at: "2018-08-30 06:19:12", updated_at: "2018-08-30 06:19:12">]
#...
I can't get the console to assign this output to a variable so I can figure out how to use this data to recreate the objects in the db:
irb(main):040:0> a = [#<Assignment id: 276503, school_id: 2091, listing_id: 251572, created_at: "2018-08-30 05:02:36", updated_at: "2018-08-30 05:02:36">, #<Assignment id: 279532, school_id: 1233, listing_id: 252702, created_at: "2018-08-30 06:19:12", updated_at: "2018-08-30 06:19:12">]
irb(main):041:1*
Does anyone have ideas how to turn this console output back into objects in my db?

If you have the problems with assigning a huge array to a variable in the console, you can try to use rake task.
array.each do |e|
options = e.split(',')
school_id = options.detect{|i| i.match?(/school_id/)}.split(':').last
listing_id = options.detect{|i| i.match?(/listing_id/)}.split(':').last
Assignment.create(school_id: school_id, listing_id: listing.id)
end
This should work. It is quite consuming, but from another perspective easy and fast.

I would paste that output on sublime or any other text editor and then format
to become something useful...
A bunch of inserts using SQL or just .create() that i would then paste it on the console

Related

Rails 4: using offset on a randomized list produces unexpected results

...or maybe, i just don't get it.
TL;DR - i get totally randomized results with duplicates and such. No idea why.
Here's the problem - i'm trying to make a rails app generating tournament brackets. The user can select whether he'd like to randomize the team list when generating the bracket, or later assign the teams by himself.
If i choose the latter option and generate the bracket as the ids go, everything is fine.
If i choose to randomize the list, the list itself is fine, but later when assigning teams to particular matches (in a loop), the resulst are completely unorganized and unexpected (at least to me) eg.
instead of
Match 1: Team 1 vs Team 2
Match 2: Team 3 vs Team 4
etc. (as in the normally generated list)
i get something completely random with frequent duplicates like:
Match 1: Team 1 vs Team 1
Match 2: Team 1 vs Team 9
if #seed = 'random'
#team_list = #tournament.teams.order("RAND()")
else
#team_list = #tournament.teams.order(:id)
end
Here's how i assign the teams. The thing that screws everything up seems to be the "offset" part, and i don't get it, why.
#match.team_a = #team_list.offset((2*match_number)-2).limit(1).first
#match.team_b = #team_list.offset((2*match_number)-1).limit(1).first
EDIT:
A sample of #team_list data as requested. That's the randomized one.
#<ActiveRecord::AssociationRelation
[#<Team id: 2, team_name: "test_team_a", reputation: 0, created_at: "2016-08-25 09:29:20", updated_at: "2016-08-26 11:08:21", team_leader_id: 2>,
#<Team id: 9, team_name: "test_team_b", reputation: 0, created_at: "2016-08-30 23:01:17", updated_at: "2016-08-30 23:01:17", team_leader_id: 2>,
#<Team id: 3, team_name: "test_team_c", reputation: 0, created_at: "2016-08-30 22:59:16", updated_at: "2016-08-30 22:59:16", team_leader_id: 2>,
#<Team id: 7, team_name: "test_team_d", reputation: 0, created_at: "2016-08-30 23:00:35", updated_at: "2016-08-30 23:00:35", team_leader_id: 2>,
#<Team id: 5, team_name: "test_team_e", reputation: 0, created_at: "2016-08-30 23:00:07", updated_at: "2016-08-30 23:00:07", team_leader_id: 2>,
#<Team id: 6, team_name: "test_team_f", reputation: 0, created_at: "2016-08-30 23:00:23", updated_at: "2016-08-30 23:00:23", team_leader_id: 2>,
#<Team id: 4, team_name: "test_team_g", reputation: 0, created_at: "2016-08-30 22:59:41", updated_at: "2016-08-30 22:59:41", team_leader_id: 2>,
#<Team id: 8, team_name: "test_team_h", reputation: 0, created_at: "2016-08-30 23:00:46", updated_at: "2016-08-30 23:00:46", team_leader_id: 2>]>
Just to shed some more light on the above answer, when you do #team_list = #tournaments.teams.order("RAND()"), that does this query (presumably in SQL):
SELECT teams.* FROM teams ORDER BY RAND()
(I know teams belongs to tournaments, but you get my point.)
And then when you do #team_list.offset(x).limit(1), that does this query:
SELECT teams.* FROM teams ORDER BY RAND() LIMIT 1 OFFSET x
Because of ActiveRecord relations, each time you do a new thing, you're doing a query. You can test this out in rails console - it'll tell you the queries it does.
EDIT:
If you want to use your code as is, just convert the result of the first query to an array and don't use offset/limit. So:
#team_list = #tournaments.teams.order("RAND()").to_a
...
#match.team_a = #team_list[2 * match_number - 2]
#match.team_b = #team_list[2 * match_number - 1]
This means that you will be loading all of the teams at once (I think) and not lazily loading them as ActiveRecord relations allow you to do.
It is because you are using offset. Each time you change the match_number you end up doing a new query (which includes the call to order_by rand()). You need to make #team_list the result of your database query and then to organize the matches in some other way so you are not hitting the database repeatedly. This will also dramatically improve performance.
Try something like
#team_list.each_slice(2) do |team_a, team_b|
end

Why can't I destroy this variable in Ruby?

In the rails console, I do this:
input = Input.create :name => "foo"
=> #<Input id: 8, name: "foo", created_at: "2013-05-07 11:45:17", updated_at: "2013-05-07 11:45:17">
Input.all
=> [#<Input id: 8, name: "foo", created_at: "2013-05-07 11:45:17", updated_at: "2013-05-07 11:45:17">]
input
=> #<Input id: 8, name: "foo", created_at: "2013-05-07 11:45:17", updated_at: "2013-05-07 11:45:17">
input.destroy
=> #<Input id: 8, name: "foo", created_at: "2013-05-07 11:45:17", updated_at: "2013-05-07 11:45:17">
> Input.all
=> []
> input
=> #<Input id: 8, name: "foo", created_at: "2013-05-07 11:45:17", updated_at: "2013-05-07 11:45:17">
> input.reload
ActiveRecord::RecordNotFound: Couldn't find Input with id=8
> input
=> #<Input id: 8, name: "foo", created_at: "2013-05-07 11:45:17", updated_at: "2013-05-07 11:45:17">
What I'd really expect to see is something like:
> input
=> nil
The object is deleted from the database but the variable still exists and is still trying to point to it. What's going on?
The input variable stores a reference to the instance in memory. Destroying the record will remove the row from the database. Calling input.reload (docs) raises an exception when attempting to find the record but doesn't set the value of your variable to nil on your behalf.
This behavior can be useful in the span of a DELETE request in which you want to display information about the object you removed. For example:
class WidgetsController < ApplicationController
def destroy
#widget = Widget.find(params[:id])
#widget.destroy
respond_with #widget, notice: "You successfully removed #{#widget.name}"
end
end
The destroy method makes the SQL call to the database and destroys the row in the table that contains it. It does still allow you to manipulate the object in the application as long as it’s still in scope (i.e) the callbacks and
filters are allowed even after destroying the object.
It is better to use "delete" if we don't want the callbacks to be triggered or if we want better performance
you can use input.delete

rspec not saving to database

I'm trying to test the login method below, but it does not seem to be saving the data_provider_user to the database. I've checked using debugger and it works perfectly until it leaves the method and goes back to the rspec code, as shown below. I've also checked to see if the object is valid after it save using .valid? and it is so I'm a bit lost!
def login
require 'TwitterOauth'
#data_provider_user = DataProviderUser.find(params[:id])
if #data_provider_user.twitter?
#request_token = TwitterOauth.request_url
#data_provider_user.access_token = #request_token.token
#data_provider_user.oauth_token_secret = #request_token.secret
if #data_provider_user.save
debugger
redirect_to #request_token.authorize_url
end
end
end
Test:
it "should update the tokens" do
require 'TwitterOauth'
TwitterOauth.stub(:request_url).and_return(#token)
debugger
get :login, {id: #data_provider_user.id}
debugger
#data_provider_user.access_token.should_not eq(nil)
#data_provider_user.oauth_token_secret.should_not eq(nil)
end
Debugger output:
#<DataProviderUser id: 84, user_id: 63, data_provider_id: 63, username: nil, password: nil, created_at: "2013-02-19 15:21:59", updated_at: "2013-02-19 15:21:59", access_token: nil, update_frequency: nil, oauth_token_secret: nil>
#<DataProviderUser id: 84, user_id: 63, data_provider_id: 63, username: nil, password: nil, created_at: "2013-02-19 15:21:59", updated_at: "2013-02-19 15:22:12", access_token: "186553918-sEAEO2fcvtyO1x99eH4Q4XwVcOYatODCQ5f1TwqD", update_frequency: nil, oauth_token_secret: "gLw2PtUyTZfxIan1gJBnbP7icboXbi98KlUoOn7ycVs">
#<DataProviderUser id: 84, user_id: 63, data_provider_id: 63, username: nil, password: nil, created_at: "2013-02-19 15:21:59", updated_at: "2013-02-19 15:21:59", access_token: nil, update_frequency: nil, oauth_token_secret: nil>
Any help would be greatly appreciated!!
------ UPDATE -------
There was actually nothing wrong with the code, the issue was that rspec was not reloading it in time. A way to get around this was to use:
#data_provider_user.reload
before hand which refreshes the object, updating the values accordingly.
There was actually nothing wrong with the code, the issue was that rspec was not reloading it in time. A way to get around this was to use:
#data_provider_user.reload
before hand which refreshes the object, updating the values accordingly.
In spec/rails_helper.rb
Set false to use_transactional_fixtures:
# If you're not using ActiveRecord, or you'd prefer not to run each of your
# examples within a transaction, remove the following line or assign false
# instead of true.
config.use_transactional_fixtures = false
Are you sure you're looking at the right database? When you're doing testing it's probably going to myapp_test (myapp being whatever you called your app). You may be looking at your myapp_development database.
If you're accessing the database via rails db chances are you're going into your development database. You can check with select database(); if you're using MySQL. If you want to check your test database, then use RAILS_ENV=test rails db. Again, you can use the select statement to verify you're in the right database.

How do I get unique elements in this array?

Using Mongoid. Unfortunately, Mongoid does not allow for selecting unique / distinct!
Have gotten these results. As you can see, there are 7 results. If you look carefully (at user_id), there are only 2 users.
[
#<Activity _id: 4cea6c4572357e00fa00011a, created_at: 2010-11-22 13:12:37 UTC, updated_at: 2010-11-22 13:12:37 UTC, action: "Attend", user_id: BSON::ObjectId('4cea2fb872357e00fa000025'), artist_id: nil, media_id: BSON::ObjectId('4cea447472357e00fa00009a')>,
#<Activity _id: 4cea6c3072357e00fa000116, created_at: 2010-11-22 13:12:16 UTC, updated_at: 2010-11-22 13:12:16 UTC, action: "Attend", user_id: BSON::ObjectId('4cea2fb872357e00fa000025'), artist_id: nil, media_id: BSON::ObjectId('4cea447472357e00fa00009a')>,
#<Activity _id: 4cea6bdd72357e00fa00010d, created_at: 2010-11-22 13:10:53 UTC, updated_at: 2010-11-22 13:10:53 UTC, action: "Attend", user_id: BSON::ObjectId('4cea2fb872357e00fa000025'), artist_id: nil, media_id: BSON::ObjectId('4cea447472357e00fa00009a')>,
#<Activity _id: 4cea46df72357e00fa0000a4, created_at: 2010-11-22 10:33:03 UTC, updated_at: 2010-11-22 10:33:03 UTC, action: "Attend", user_id: BSON::ObjectId('4cea2fb872357e00fa000025'), artist_id: nil, media_id: BSON::ObjectId('4cea447472357e00fa00009a')>,
#<Activity _id: 4cea40c572357e00fa00006f, created_at: 2010-11-22 10:07:01 UTC, updated_at: 2010-11-22 10:07:01 UTC, action: "Attend", user_id: BSON::ObjectId('4cea2fb872357e00fa000025'), artist_id: nil, media_id: BSON::ObjectId('4cea3c8b72357e00fa00005e')>,
#<Activity _id: 4cea3ca172357e00fa000062, created_at: 2010-11-22 09:49:21 UTC, updated_at: 2010-11-22 09:49:21 UTC, action: "Attend", user_id: BSON::ObjectId('4cea39b772357e00fa000046'), artist_id: nil, media_id: BSON::ObjectId('4cea3c8b72357e00fa00005e')>,
#<Activity _id: 4cea344a72357e00fa00003f, created_at: 2010-11-22 09:13:46 UTC, updated_at: 2010-11-22 09:13:46 UTC, action: "Attend", user_id: BSON::ObjectId('4cea2fb872357e00fa000025'), artist_id: nil, media_id: BSON::ObjectId('4cea306c72357e00fa000031')>
]
I was looking at this, and was thinking I could do something similar so that my array would now look like this:
[
#<Activity _id: 4cea6c4572357e00fa00011a, created_at: 2010-11-22 13:12:37 UTC, updated_at: 2010-11-22 13:12:37 UTC, action: "Attend", user_id: BSON::ObjectId('4cea2fb872357e00fa000025'), artist_id: nil, media_id: BSON::ObjectId('4cea447472357e00fa00009a')>,
#<Activity _id: 4cea3ca172357e00fa000062, created_at: 2010-11-22 09:49:21 UTC, updated_at: 2010-11-22 09:49:21 UTC, action: "Attend", user_id: BSON::ObjectId('4cea39b772357e00fa000046'), artist_id: nil, media_id: BSON::ObjectId('4cea3c8b72357e00fa00005e')>
]
I'm not concerned which combination of results are extracted. As long as I have unique user_id's in the result set. Anyone know how this can be achieved?
You can just use the method uniq. Assuming your array is ary, call:
ary.uniq{|x| x.user_id}
and this will return a set with unique user_ids.
This should work for you:
Consider Table1 has a column by the name of activity which may have the same value in more than one record. This is how you will extract ONLY the unique entries of activity field within Table1.
#An array of multiple data entries
#table1 = Table1.find(:all)
#extracts **activity** for each entry in the array #table1, and returns only the ones which are unique
#unique_activities = #table1.map{|t| t.activity}.uniq
For those hitting this up in the future, you can now use the Mongoid::Criteria#distinct method from Origin to select only distinct values from the database:
# Requires a Mongoid::Criteria
Attendees.all.distinct(:user_id)
http://mongoid.org/en/mongoid/docs/querying.html (v3.1.0)
Have you looked at this page?
http://www.mongodb.org/display/DOCS/Aggregation#Aggregation-Distinct
That might save you some time?
eg
db.addresses.distinct("zip-code");
Instead of using an Array, consider using either a Hash or a Set.
Sets behave similar to an Array, only they contain unique values only, and, under the covers, are built on Hashes. Sets don't retain the order that items are put into them unlike Arrays. Hashes don't retain the order either but can be accessed via a key so you don't have to traverse the hash to find a particular item.
I favor using Hashes. In your application the user_id could be the key and the value would be the entire object. That will automatically remove any duplicates from the hash.
Or, only extract unique values from the database, like John Ballinger suggested.
Errr, it's a bit messy in the view. But I think I've gotten it to work with group (http://mongoid.org/docs/querying/)
Controller
#event_attendees = Activity.only(:user_id).where(:action => 'Attend').order_by(:created_at.desc).group
View
<% #event_attendees.each do |event_attendee| %>
<%= event_attendee['group'].first.user.first_name %>
<% end %>

Error with "to_sql" on Rails 3 Beta 4

I'm testing Rails 3 beta 4 on Ruby 1.9.2-head, and when I start a
console and do:
Game.first.to_sql
I get this error:
ArgumentError: wrong number of arguments (0 for 1)
I know it can find the Game record, because when I type:
Game.first
it returns:
=> #<Game id: 1, name: "Galaga", created_at: "2010-06-19 11:02:37",
updated_at: "2010-06-19 11:02:37">
What am I missing? I just want to make the to_sql work in a very simple
case.
.
When you run Game.first you are returning a Game object, not a ActiveRecord::Relation object as you are expecting.
To do what you're trying to do, you'll need to do:
Game.limit(1).to_sql
This lets you run it without to_sql and return the object as you expected it, although it will be in an array, which then you can run .first on it like you wanted anyways.
irb(main):004:0> Game.limit(1).to_sql
=> "SELECT `games`.* FROM `games` LIMIT 1"
irb(main):005:0> Game.limit(1).class
=> ActiveRecord::Relation
irb(main):006:0> Game.limit(1)
=> [#<Game id: 1, name: "Galaga", created_at: "2010-06-19 11:02:37", updated_at: "2010-06-19 11:02:37">]
irb(main):007:0> Game.limit(1).first
=> #<Game id: 1, name: "Galaga", created_at: "2010-06-19 11:02:37", updated_at: "2010-06-19 11:02:37">
When you dig into the source, when you run .first on an ActiveRecord::Relation it runs the following (which is the same as I showed you):
def find_first
if loaded?
#records.first
else
#first ||= limit(1).to_a[0]
end
end

Resources