I am working on a sinatra app with datamapper connected to a mysql database and am having problems retrieving/finding records from only one specific table. I can insert into it with datamapper find but when I try to do #sleepEntries = Sleep_Log.all I get the following error: ArgumentError: argument out of range. When I load everything into irb I get the same error. I also turned on the ability to see the queries and I get back SELECT id, start_time, length, timestamp FROM sleep_logs ORDER BY id when I call Sleep_Log.all. When I connect to the mysql database through the mysql command line tool I can confirm that there are entries in that table. When I run the query that datamapper is erroring out on I have no problem getting the results. Here is my datamapper model info for Sleep_Log
class Sleep_Log
include DataMapper::Resource
property :id, Serial
property :start_time, Time, :required => true
property :length, Integer, :required => true
property :timestamp, DateTime, :writer => :private
belongs_to :user
end
This is what the table looks like in the database accessed through describe sleep_logs;
What is weird is that retrieve results from all other tables.
The backtrace from irb
If you try Sleep_Log.first, do you get the error? If so, could you paste in the record, or one which also shows the error?
How was the table constructed? Are you using DM to inspect already entered records? Or are you entering them through DM too?
We just encountered the exact same problem. In our case it turned out that you have to use DateTime. Mysql doesn't have a Time database type and saves as DateTime. However, DataMapper doesn't get it and blows up. If you switch your model to use DateTime DM will get it.
Related
When I have a column named "fullname" in the existing model, I want to set a limit of 50 characters to store in that column. What is the best method to achieve this? Use rails migrate? or code something in app/models to do syntax checking?
You should really do both. You want your database to enforce your data restrictions as this prevents any bugs in your application code from allowing invalid data. Create a rails migration to alter the data type of your column. For example...
change_table :table_name do |t|
t.change :column_name, :string, :limit => 50
end
You should also ensure the data is less than 50 characters in your application code, otherwise you will get an error if you try to insert a value greater than 50 characters. The rails way to do this would be an Active Record Validation in your model. See this link for info on Active Record validations
I have a question.
Devise and mailboxer are installed on my rails app without any problem.
The problem is that you have to use "email" or "name" column to associate devise user with mailboxer.
Obviously, devise doesn't have column called "name" in Users table.
So, if you use "email" then users will see everyone else's email address that they wanna hide.
I want twitter-like registration.
They've got unique_id(account name) that never will be changed.
To achieve that, How can I?
I. Add column named "unique_id" to Users table?
command: rails g migration AddUniqueIdToUsers unique_id:string
to create migration file, and open and edit like this
class AddUniqueIdToUsers < ActiveRecord::Migration
def change
add_column :users, :unique_id, :string
add_index :users, :unique_id, :unique => true
end
end
II. How do I associate devise with mailboxer by using "unique_id" column?
Thanks in advance
Obviously, devise doesn't have column called "name" in Users table
That is entirely up to you, all Devise does (or wants you to do) is add a few records that tell it how to function. If you look at the devise generator you can see that all it does is add a couple of columns to your migration.
I want twitter-like registration. They've got unique_id(account name) that never will be changed. To achieve that, How can I?
First of all, a unique ID is always given to you by free in Rails (indeed, in most typical web applications using a database backend, each row has a unique ID).
But, if you also want users to select a username, and have that be unique as well, the you could do as the mailboxer readme states and simply override the usage of name with your own database column like username, like so:
Mailboxer.setup do |config|
# ...
#Configures the methods needed by mailboxer
config.email_method = :email
config.name_method = :username
# ...
end
Or, if you want to stay out of the mailboxer config file, you can simply use alias_method and do this (given that you have a username column):
class User < ActiveRecord::Base
alias_method :name, :username
acts_as_messageable
end
Either way, Devise doesn't restrict you in which columns you use on your User model, and it seems that Mailboxer also doesn't restrict you in which columns you use to attach the gem to the User model. So you have as much flexibility as you want without having to built this functionality by yourself.
Recently i added PostgreSQL to my application which was already running on MySQL, now application is running on two databases. I was able to establish associations between the tables present in different database and its working fine. Today i added a search feature in a page which uses tables present in two databases and its throwing an error. Spent all day trying to figure out the bug but didn't succeed. Please look into the associations,code and help me correct it.
I have 4 tables:-
Company(mysql)
Location(mysql)
Report(PostgreSQL)
Report_category(PostgreSQL)
model - company.rb
establish_connection Rails.env+"_postgres"
has_many :reports
establish_connection Rails.env
belongs_to :location
location.rb
has_many :companies
report.rb
establish_connection Rails.env
belongs_to :company
establish_connection Rails.env+"_postgres"
belongs_to :report_category
report_category.rb
establish_connection Rails.env+"_postgres"
has_many :report
Now from view i pass the search parameters and in my reports_controller i write
#reports = Report.where("companies.name like ? and report_category.name ?", params[:company], params[:category]).includes(:company, :report_category)
after executing this line i'm getting the below error
ActiveRecord::StatementInvalid: PGError: ERROR: relation "companies" does not exist
but
Company.where("location.name like ?", params[:location]).includes(:location)
or
Report.where("report_categories.name like ?", params[:category]).includes(:report_category)
works perfectly fine. I only get the error if i search using two databases. Please do help
First I want to second the suggestion in the comments that you move everything onto one db. This saves you a lot of complexity down the road. However if you really can't do this, there are a couple ways you can access the MySQL tables from within PostgreSQL, and this would be a second-class solution to a full migration, but it would work.
In PostgreSQL 9.1 and higher you can do read-only queries using foreign data wrappers for MySQL. In earlier versions you can use David Fetter's DBI-Link project to make the connection.
These then allow you to present your data as a unified database to your applications.
So as I was following the Ruby on Rails Tutorial by Michael Hartl I noticed that in the users table we added a unique index for the :email attribute to improve the efficiency of the find method so it doesn't search row by row. So far we have been searching using both find_by_email and find_by_id depending on the case. Yet we never set up an index for the :id attribute. Is :id automatically indexed because it is by default unique and sequential in nature? Or is this not the case and should I add an index for :id searching?
Most databases (sqlite included, which is the default db in RoR) automatically index the primary key, which with Rails Migrations is :id by default.
I'm running an import script which imports a CSV dump of a database into a local sqlite database using DataMapper.
My models look like this:
class Staff
include DataMapper::Resource
property :staff_id, String, :key => true
property :full_name, String
end
class Project
include DataMapper::Resource
property :project_id, Integer, :key => true
property :title, String
property :status, String
belongs_to :staff
end
The CSV contains the primary key so when I'm do the import I'm using that as it's key. Next time I run the import I clear the tables and start again, however datamapper moans because the primary keys have already been taken.
Is there a way to stop datamapper moaning about this or should I just delete the .db file and re-create an empty .db file just before the import runs? If so what's the easiest way to do this.
You can use DataMapper.auto_migrate! to blow away the tables, and then recreate them matching the current model state. The new tables will be empty of any data from previous runs.
So just after you define your models, but before you begin importing the data do something like the following:
DataMapper.finalize.auto_migrate!
If you create the complete DB from the import, I'd really recommend nuking the database completely to avoid any spill-over from earlier runs. This also keeps your build-db code path well tested.