MySQL active record problem writing to newly created table - mysql

My code is:
# require gems
require 'rubygems'
require 'active_record'
# Start connetion to the server
ActiveRecord::Base.establish_connection(
:adapter => "mysql",
:host => "localhost",
:user => "root",
:password => "password",
:database => "data"
)
# Create the table
ActiveRecord::Schema.define do
create_table :datatable do |table|
table.column :date, :string
table.column :word, :string
table.column :website, :string
end
end
class Table < ActiveRecord::Base; end
Table.create(:date => datenow, :word => someword, :website => mywebsite)
puts "code completed"
And I get an error when the code wants to write to the table saying:
path/to/mysql_adapter.rb:287:in 'query': Table 'test.tables' doesn't exist (Mysql::Error)
If I create a table that is called tables within the database (data) then all of my data is put into there. I want to it to be written to the table (datatable) I have just created. How can I do this and solve the error?

The error is to be expected. You're accessing a table called table, but creating a table called datatable.
To configure your Table model to use the datatable table, use ActiveRecord::Base.set_table_name like so:
class Table < ActiveRecord::Base
set_table_name 'datatable'
end
Alternatively, you could rename your model to Datatable.
However, I'd suggest you rename it to something entirely different. Unless you're actually storing data about tables, your model probably shouldn't be called Table. WebsiteWord comes to mind or WordOccurrence or perhaps just Word. I have a feeling it'll save you pain in the long run.

Related

How to customise a key in json response?

Relationship: Table has many Users.
I'm using "includes" to print the table details with the associated users as:
Table.includes(:users)
But if I use conditions for users, say, users.active as:
Table.includes(:users).where( :users => { active: true } )
I'm getting the tables with users that are active. That works good. But if a table doesn't have active user, it returns empty.
What I need was, to print the table details even if there is no active user (in that case, excluding the user part). i.e., if there is any active user, it has to be printed along the table else only table has to be printed.
So I wrote a filter method in model as:
has_many :active_users, class_name: "User", :conditions => { active: 'yes'}
And, in controller: Table.includes(:active_users).
Now, for json response:
render :json => { :table => #table.as_json(:include => :active_users) }
So the key comes as "active_users".
But I like to have that key as "users" and i'm stuck finding solutions. Can anyone suggest a sol please.
TIA!
Override the Table#as_json to include the users
def as_json(opts={})
super.merge(
users: active_users.as_json(only: [:id, :username, ...]
)
end
I'd recommend whitelisting the user attributes to ensure you don't expose any sensitive information.

How do I construct the proper before_destroy in model in rails

I have the following which deletes a bin and everything related to it. It's great and functions;
MODEL BIN
class Bin < ActiveRecord::Base
has_many :savedtweets, :dependent => :destroy
before_destroy :mod_newtweets
def mod_newtweets
Newtweet.where(:tweet_id => #bin.savedtweets.pluck(:tweet_id)).update_all(:status => 'new')
end
end
However, it destroys a bin, deletes everything but doesn't run :mod_newtweets to update my other table and its column.
If I put this in the controller it works fine;
Newtweet.where(:tweet_id => #bin.savedtweets.pluck(:tweet_id)).update_all(:status => 'new')
I thought I've got everything done right.
Replace your method with:
def mod_newtweets
Newtweet.where(:tweet_id => savedtweets.pluck(:tweet_id)).update_all(:status => 'new')
end
You are using #bin.savedtweets in your model while you have not defined #bin anywhere. as it is an instance method you can use either self.savedtweets or only savedtweets to call the savedtweets method on current instance of Bin model.

Multiple models accessing same table

I am new to Datamapper and Ruby on Rails. I have an en existing model A, now I want to create another version of model A, v2_A. The difference between A and V2_A is that I have changed a few belongs_to from A to v2_A by changing :required => true to :required => false like following.
class A
include DataMapper::Resource
property :p1, ...
...
belongs_to :b, :required =>true
end
class v2_A
include DataMapper::Resource
property :p1, ...
...
belongs_to :b, :required =>false
end
So basically all column names in resulting tables will be same. Whenever I am doing rake db:autoupgrade a new table v2_A is being created which is not desired. I am asking is it possible both of the models access the same table A i.e. I don't want v2_A to create another table just because of that.
i am not sure about DataMapper::Resource
But i guess in your model you can write
self.table_name = "name_of_your_table"
In both of the model.

How do I get the resultset of a ActiveRecord query for a table that does not have a model?

I need to connect to the data in a remote MySQL table, iterate through it, and use ActiveRecord "create" methods so that all validations and callbacks are performed. I have found documentation for having multiple database config settings, and assigning them individually per model, but that doesn't fit my needs because I don't want to create models or migrations for a one time import.
So I found this other method of querying a database outside of AR:
base = ActiveRecord::Base.establish_connection(
:adapter => "mysql2",
:host => "XXX",
:username => "YYY",
:password => "ZZZ",
:database => "AAA"
)
results = base.connection.execute("SELECT * FROM programs WHERE 1")
But it returns an object that looks fairly inscrutable:
#<Mysql2::Result:0x007fdf6e8bb9d8>
Any ideas?
This does the trick:
base.connection.select("SELECT * FROM programs WHERE 1")
Look at ActiveModel. You can put all of the functionality you need in there and have access to things such as validations.

Rails 3.1 Qeurying the database encrypted with attr_encrypted gem (where clause on encrypted fields)

I have encrypted a field in the table using the attr_encrypted gem. Now I want to query on that particular field comparing it with a value I am retrieving from a form. How can I do this?
EDIT : I need to query on a number of encrypted fields. Eg: searching on encrypted_email, encrypted_name etc. (using OR condition in where clause)
attr_encrypted intercepts find_by methods, so you should be able to do this:
class User < ActiveRecord::Base
attr_encrypted :email, :key => 'a secret key'
attr_encrypted :password, :key => 'some other secret key'
end
User.find_by_email_and_password('test#example.com', 'testing')
This is rewritten as
User.find_by_encrypted_email_and_encrypted_password('ENCRYPTED EMAIL', 'ENCRYPTED PASSWORD')
class User < ActiveRecord::Base
attr_encrypted :email, :key => 'a secret key'
end
If you want to write a query to retrieve user whose email is 'abc#xyz.com' then you can do either
User.where(encrypted_email: User.encrypt_email('abc#xyz.com'))
or
User.scoped_by_email('abc#xyz.com') # works only for dynamic scope methods