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.
Related
I am using Cequel as ORM for Cassandra without rails.
I have a problem when trying to create a simple list of projects.
First I defined the model with three columns which should belong to a compound key.
class Project
include Cequel::Record
key :client, :text, { partition: true }
key :type, :text, { partition: true }
key :dep, :text, { partition: true }
end
Later when I try to create the Project via
project = Project.create!({client: "test", type: "test", dep: "test"})
I get an error that the table does not exist.
The tables are not created automatically with Project.create! but I have to create the table manually first:
connection.schema.create_table(:projects) do
partition_key :client, :text
partition_key :type, :text
partition_key :dept, :text
end
But this syntax is different from the documented Record definition and I only found it by sifting through the source code. But this creates two problems.
Code overhead
I don't know the syntax for has_many and belongs_to so I cannot create the table correctly if the Record includes this
Am I overlooking a method to create the table automatically from the Project class definition?
The tables can be created by calling the method synchronize_schema on the class. So, in your case, you should execute Project.synchronize_schema before actually attempting to read/write into it.
Given that you are building a broader project, you can consider using Rake tasks for it. You also need to migrate so that the tables are actually created in Cassandra. You can use rake cequel:migrate for that. There are more tasks which you can see via rake --tasks.
If you are creating your custom project with custom places for models, you probably need to hack the rake migration task a little. This is an implementation that I did for my project https://github.com/octoai/gems/blob/master/octo-core/Rakefile#L75. Also take a look at how models are defined https://github.com/octoai/gems/tree/master/octo-core/lib/octocore/models
Hope this helps.
Using Rails 3.2.2 and ruby 1.9.3dev and mysql
I am new to ruby and rails. We have an existing database with a couple hundred tables. We would like to try out rails to see if it would be a positive change from PHP & ZendFramework.
Migrating data into another database is not an option for us because we have several other applications currently using this database. We wanted to "attach" a rails project to the existing database.
The part I am struggling is generating all the models from our existing database.
I seen a couple of older posts talking about some automated techniques including Magic Model Generator. While others talked about there is no way to do this, or you just have create them all manually.
I was not successful in generating models using Magic Model Generator (perhaps rails 2 only?)
Long ago, when we switched to ZendFramework, I wrote a quick script to analyze the database and generate all the model files for us. It would seem this would be a somewhat common scenario.
Note: We use ID instead of id and many have many foreign_key relationships.
So I wanted to ask the community what is the best (way/practice) to handle this?
It's not that difficult, just takes a bit more configuration. Here's a basic template for a model:
class YourIdealModelName < ActiveRecord::Base
self.table_name = `actual_table_name`
self.primary_key = `ID`
belongs_to :other_ideal_model,
:foreign_key => 'foreign_key_on_other_table'
has_many :some_other_ideal_models,
:foreign_key => 'foreign_key_on_this_table',
:primary_key => 'primary_key_on_other_table'
end
I am no expert and even had researched about this.
Without thinking to much first solution in my mind is to make the models and migrations according to the rails way so you don't have any problem, for example key and foreign key naming. If you have already some data you should migrate it to the rails db.
One reason to do this is that models are suppose not to be only data accessors but also contain the business logic
I'm looking for a suggestion on how to set up two models, Teacher and Subject. A Teacher can have many Subjects, and a Subject can have many Teachers. Another thing to consider in the relationship between the two models is that a Teacher can create a Subject and add other Teachers to the Subject.
I think I'm solid on the basics of the set up for each model:
for teacher.rb:
has_many :subjects
for subject.rb:
has_many :teachers
and the teachers table should have a subject_id column and the subject table should have a teacher_id column.
What I'm not sure about is how to set up the views (and corresponding controller methods) to allow the addition of a Teacher to a Subject.
Any suggestions (or links to examples) are greatly appreciated. I haven't been able to find anything on this exact case.
current set up:
standard CRUD for a Student object
standard CRUD for a Project object
I'm likely missing something simple in how to tie these models together (other than the part of changing has_many to habtm) and getting records into the subjects_teachers table, and I still can't find a good example...
You need to build the relational table between them. It's impossible to have a many-many relationship without a rel table
First off though, it's a has_and_belongs_to_many :subjects and has_and_belongs_to_many :teachers (commonly referred to as habtm)
http://guides.rubyonrails.org/association_basics.html#the-has_and_belongs_to_many-association
run
rails g migration subjects_teachers
open up the migration:
create_table :subjects_teachers, :id => false do |t| # ID => FALSE = IMPORTANT
t.references :subject
t.references :teacher
# NO TIMESTAMPS
end
run
rake db:migrate and you should be set!
then
see these railscasts for setting up your controllers
http://railscasts.com/episodes/17-habtm-checkboxes
http://railscasts.com/episodes/47-two-many-to-many
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.
I have two tables, users and groups. A user can belong to many groups. A group can have many users.
So I have created a have_and_belongs_to_many relationship between users and groups using a join table, groups_users. This all works as expected.
What I would also like to do is specify an ACTIVE group for each user. Were it not for the habtm relationship I have already defined, I would create a column “group_id” in users for the active group, and then I would define a one-to-many relationship between the models as follows:
class User < ActiveRecord::Base
belongs_to :group
end
class Group < ActiveRecord::Base
has_many :users
end
This didn’t work. I could not access group properties like “#user.group.name”. I suspect that I’m asking too much of Rails by specifying two relationships.
So I have three questions.
I could very easily understand if combining the two relationships confuses Active Record . Is that the case?
If so, how would you implement these relationships? Right now I’m just manually using the group_id, but that feels messy.
Regardless of whether I am using Active Record magic or manually setting the active group, it is possible for a user’s active group to be outside the group’s they belong to using the first habtm relationship. Any thoughts on how to implement this with the constraint that the active group must be a group that the user belongs to?
Thanks for any insights. I am a couple of weeks into the Rails learning curve and I think that getting to the bottom of this little problem will deepen my understanding of models and table relationships quite a bit.
Greg - I've done this before, similar to what as your proposing. I used a "primary_group" instead of "group" and set the foreign_key to be "primary_group_id" and the :class_name => 'Group'
I don't use has_and_belongs_to_many very often so I don't know if that would be causing an issue, but I don't think so - at least not with the user model. You don't have a #group method, so setting belongs_to should be OK. I don't know if you absolutely must have have a has_many :users method on the group, but you may not need it anyway. This will certainly cause a collision with the 'users' method that habtm creates. If you do need this, try has_many :primary_users and set the :foreign_key => :primary_group_id
Just some thoughts. You should be able to do what you're doing now, so not sure what's failing.