Activerecord Rails 3 string limits not working - activerecord

I have a rails migration and I am most probably doing something incorrect here but
the migration is ---
class CreateStates < ActiveRecord::Migration
def change
create_table :states do |t|
t.string :state_legacy_id
t.string :name, :length => 20
t.string :abbreviation, :length => 2
t.timestamps
end
add_index :states, :id
end
end
But when i go into mysql database and look at the table the name table as well as the abbreviation table have a length of varchar/ 255 What is about my limit statement that is incorrect.
I have tried both with and without quotes, so :limit => 20 and :limit => "20" both product tables with varchar 255.
Any suggestions will be welcome.
Thanks,

i believe it's called limit - not length
e.g. :limit => 2

Related

Creating an ActiveRecord database for a webcrawler. Having issues adding index

I'm working on a three part program for a webcrawler program for school. My first step is to just create the database using activerecord and knowing that it will be queried later using sqlite3. The database actually does get created with my current program. However, it errors out when gets to "add_index". I'm not great with databases in general so guidance is appreciated.
Before I put in my code the error is:
crawler_create.rb:23: syntax error, unexpected ',', expecting ')'
add_index (:pages,[:url], unique=> true)
Here's what I've come up with so far:
require 'active_record'
require 'sqlite3'
db=SQLite3::Database.new("crawler.db")
ActiveRecord::Base.establish_connection(adapter:'sqlite3',database:'crawler.db')
ActiveRecord::Schema.define do
create_table :pages do |t|
t.string :url, :null => false
t.string :title
t.string :content_type
t.date :last_modified
t.string :status
end
end
add_index (:pages,[:url], unique=> true)
ActiveRecord::Schema.define do
create_table :links do |t|
t.integer :from_page_id, :null => false
t.integer :to_page_id, :null => false
end
end
add_index(:links,[:from_page_id,:pages_id], :unique =>true)
ActiveRecord::Schema.define do
add_foreign_key :from_page_id, :pages_id
add_foreign_key :to_page_id,:pages_id
end
It looks like you got a simple syntax error here:
add_index (:pages, [:url], unique: true)
I'd suggest that you use a consistent hash syntax, either using hash rockets => or the newer syntax unique: true.

Mysql2::Error: after updating to Rails 4.1

I recently updated my Rails app from 4.0 to 4.1. Everything seems to work fine, except this one line in my Search Model that was working before.
Essentially, I want to search/find District_Resources by Tag Name and by the District_Resource Name.
**ex.**
If I search the word "Tutoring"
*I should get all District_Resources with the Resource_Tag "Tutoring"
*And all District Resources that include the word Tutoring in it's Name.
(i.e Tutoring Services)
For some reason, I keep getting this error:
(Mysql2::Error: Unknown column 'resource_tags.name' in 'where
clause': SELECT `district_resources`.* FROM `district_resources`
WHERE (resource_tags.name like '%Tutoring%' OR district_resources.name like '%Tutoring%')
ORDER BY `district_resources`.`name` ASC):
But that column does exist in the Resource_Tags table.
MODELS
class DistrictResource < ActiveRecord::Base
has_many :district_mappings, dependent: :destroy
has_many :resource_tags, through: :district_mappings
accepts_nested_attributes_for :resource_tags
end
class ResourceTag < ActiveRecord::Base
has_many :district_mappings, dependent: :destroy
has_many :district_resources, through: :district_mappings
end
class Search < ActiveRecord::Base
def district_resources
#district_resources ||= find_district_resources
end
def find_district_resources
district_resources = DistrictResource.order(:name)
district_resources = district_resources.includes(:resource_tags).where("resource_tags.name like :name OR district_resources.name like :name", {:name => "%#{name}%" })
district_resources
end
end
SCHEMA
create_table "district_resources", force: true do |t|
t.string "name"
t.string "description"
t.string "website"
t.string "phone"
t.string "email"
t.datetime "created_at"
t.datetime "updated_at"
end
create_table "district_mappings", force: true do |t|
t.integer "district_resource_id"
t.integer "resource_tag_id"
t.datetime "created_at"
t.datetime "updated_at"
end
create_table "resource_tags", force: true do |t|
t.string "name"
t.datetime "created_at"
t.datetime "updated_at"
end
You are referencing district_resources in where clause but this is not joined in query as you are eager loading resource_tags so here are two solutions for this
1.
district_resources = district_resources.joins(:resource_tags).where("resource_tags.name like :name OR district_resources.name like :name", {:name => "%#{name}%" })
2.
district_resources = district_resources.includes(:resource_tags).refereces(resource_tags).where("resource_tags.name like :name OR district_resources.name like :name", {:name => "%#{name}%" })
In both of these cases we are telling rails that we are using resource_tags table in where clause so join district_resources with it
Fixed it!!
district_resources = district_resources.includes(:resource_tags).where("resource_tags.name like :name OR district_resources.name like :name", {:name => "%#{name}%" }).references(:resource_tags)
I had to reference the Resource_Tags Model

Add column to schema before created_at column

I'm trying to add a column to my table.
Here is my migration file:
class AddEmail < ActiveRecord::Migration
def change
add_column :apps, :email, :string, after: :website
end
end
However, when I run it, the newly created email column goes all the way to the last column after updated_at:
ActiveRecord::Schema.define(version: 20141217210326) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
create_table "apps", force: true do |t|
t.string "name"
t.string "iTunes"
t.string "website"
t.datetime "created_at"
t.datetime "updated_at"
t.string "email"
end
end
What I want is for the new email column to go in between the website and created_at column. How do I do that?
Postgres doesn't support the ordering of columns in tables. If you don't have any code in production, just alter the original migration that creates the apps table.

rails joins with module name

Here is how to join two models
User.where(:id => 1).joins(:posts)
but how to join two models with module/namspace
#schedules= Swimming::Classschedule.joins(:Swimming::Slot).where(:date => #date)
seems not working properly (with error message)
:Swimming is not a class/module
UPDATE
I have updated to
#schedules= Swimming::Classschedule.joins(:swimming_slots).where(:date => #date)
and I do have this table
create_table :swimming_classschedules do |t|
t.integer :slot_id
t.integer :coach_id
t.integer :level_id
t.string :note
t.timestamps
end
create_table :swimming_slots do |t|
t.string :date
t.string :start
t.string :end
t.timestamps
end
Howcome I got this error
Association named 'swimming_slots' was not found; perhaps you misspelled it?
update 2
add this line to Swimming::Classschedule module
belongs_to :swimming_slots ,:class_name=>'Swimming::Slot',:foreign_key => "slot_id"
and
change joins to
#schedules= Swimming::Classschedule.joins(:swimming_slots).where(:swimming_slots =>{:date => #date})
Now it works
you pass the association name to joins. for example, if you have an association like
has_many :swimming_slots, class_name: 'Swimming::Classschedule'
then you pass swimming_slots and rails will do the joins for you.
User.joins(:swimming_slots)
UPDATE:
if slot_id refers to a record in the swimming_slots table, you should have something like
belongs_to :slot, class_name: 'Swimming::Slot'
in your class schedule model. If you have that, you should be able to do
Swimming::Classschedule.joins(:slot)

How to use created_at value as default in Rails

How can I set one of my database table to created_at as default value. I did this but didn't work, I have checked in the DB and the value of code is null.
class CreateEvents < ActiveRecord::Migration
def change
create_table :events do |t|
t.string :title
t.string :location
t.text :description
t.date :occurs_on
t.string :code, :default => Event::created_at
t.timestamps
end
end
end

Resources