Using Rails 3, I've changed the name of a table in the model like this:
# app/models/product.rb
class Product < ActiveRecord::Base
set_table_name "items"
end
But when I try setting up tests, I get the following error:
Started
E
Finished in 0.027396 seconds.
1) Error:
test_the_truth(CustomerTest):
ActiveRecord::StatementInvalid: Mysql2::Error: Table 'project2_test.products' doesn't exist: DELETE FROM `products`
1 tests, 0 assertions, 0 failures, 1 errors
Any idea how I can let it know about Products?
OK found the answer here:
http://www.missiondata.com/blog/systems-integration/80/rails-fixtures-with-models-using-set_table_name/
Had to change the name of the Fixture yml file from Products to Items.
Rather than alter the class directly, you should create a migration. This will allow Rails to smoothly change the database, and allow any others working on the project to change their database in the same manner.
Write a change method which uses rename_table.
class RenameProductsToItems < ActiveRecord::Migration
def change
rename_table :items, :products :string
end
end
Related
Iam working in ruby on rails for fetching the existing db tables from remote server mechine(SQL SERVER) .Actually i don't know how to do this.Am following this way.please rectify me
My problem is while tying to run uninitialized constant TrDeviceDetailsController::TRDeviceDetail is getting.
I set the following in database.yml file.
development:
adapter: sqlserver
mode: odbc
database: BObd
dsn: newdb_64
username: ush
password: Ushu
host: ws1a20\SQLEXPRESS
The table exist in the db BOdb is TRDeviceDetails.I created models and controller using the command
rails generate model `TRDeviceDetail`
rails generate controller `TRDeviceDetails`
And in controller i put the following
class TrDeviceDetailsController < ApplicationController
def show
#devices = TRDeviceDetail.find(:all)
end
end
model file
class TrDeviceDetail < ActiveRecord::Base
# attr_accessible :title, :body
attr_accessible :UniqueDeviceID
end
where UniqueDeviceID is the existing column in table TrDeviceDetails
and created a show.html.erb file for displaying the UniqueDeviceID
<h1>TrDeviceDetails#show</h1>
<p>Find me in app/views/tr_device_details/show.html.erb</p>
<%#device.inspect%>
what i need is,get existing tables from remote machine.How it is possible and why this error is occurring?
you should use
#devices = TrDeviceDetail.find(:all) # small 'r'
as the generated class is
class TrDeviceDetail < ActiveRecord::Base
UPDATE:
If the table name is not something that follows convention, you should set the table_name explicitly
class TrDeviceDetail < ActiveRecord::Base
set_table_name 'TRDeviceDetails'
end
Okay, I didn't create this code, but I do need to find a good way to test it. We have been using factory_girl and minitest, but have a number of issues. I'm hoping to be able to move to Rspec and the Fabrication gems to setup some new tests, however I've run into a problem with cyclic dependencies. We have something like the following:
class Owner < ActiveRecord::Base
:validates has_inner?
def has_inner?
# Make sure we have an inner object
end
end
class Inner < ActiveRecord::Base
:belongs_to :owner
end
And I have Fabricators for each, something like:
Fabricator(:owner) do
inner
end
Fabricator(:inner) do
end
Anyone have any ideas on how I can pull this off? Is it possible?
I don't see any relationship defined from Owner to Inner. Is it a has_many? A little more details would be great.
In rails 2 I had a lib/migration_helpers.rb file with methods for setting and dropping foreign keys in the db.
These methods were available in self.up and self.down in migration files by adding in the migration file
require 'migration_helpers'
at the top, and
extend MigrationHelpers
immediately after the class statement.
In rails 3 this does not work, and if i try to run a migration using set_foreign_key method from migration_helpers.rb the following error is thrown:
== AddFkToArticles: migrating ================================================
-- set_foreign_key("articles", "book_id", "books")
rake aborted!
An error has occurred, this and all later migrations canceled:
undefined method `set_foreign_key' for #<AddFkToArticles:0x000001034a1f38>
Tasks: TOP => db:migrate
(See full trace by running task with --trace)
I already checked that in config/application.rb the autoload path is set to include lib.
The file is effectively required, because if i comment out the require statement then rails whines about the missing 'migration_helpers' file.
I suspect this is a scoping problem (rails 2 used "def self.up", rails 3 uses "def change")
but cannot imagine how to solve the problem (by now I simply copied the code in the migration file, just to check that it does what it should do).
Francesco
I don't know what exactly you're trying to accomplish but here's some code that might give you a clue.
## lib/test_helper.rb
module TestHelper
def my_table_name
return :mytable
end
end
And then the migration:
## db/migrate/test_migration.rb
include TestHelper
class TestMigration < ActiveRecord::Migration
def self.up
create_table my_table_name
end
def self.down
drop_table my_table_name
end
end
Including this helper inside the Migration class doesn't work so it should be outside.
I am pretty sure I am missing a basic mistake here, so I am hoping another set of eyes might help. I am using Rails 3, Ruby 1.9.2 and Rspec 2.
I would like to define dynamic class methods on a model so that I can return base roles for an assignable object (such as account) as they are added to the system. For example:
BaseRole.creator_for_account
Everything works fine via the console:
ruby-1.9.2-p180 :003 > BaseRole.respond_to?(:creator_for_account)
=> true
but when I run my specs for any of class methods, I get a NoMethodError wherever I call the method in the spec. I am assuming that something about how I am dynamically declaring the methods is not jiving with RSpec but I cannot seem to figure out why.
The lib dir is autoloaded path and the methods return true for respond_to?.
# /lib/assignable_base_role.rb
module AssignableBaseRole
def self.included(base)
base.extend(ClassMethods)
end
module ClassMethods
BaseRole.all.each do |base_role|
role_type = RoleType.find(base_role.role_type_id)
assignable_name = base_role.assignable_type.downcase
method = "#{role_type.name}_for_#{assignable_name}"
define_method(method) do
self.where(:role_type_id => role_type.id,
:assignable_type => assignable_name).first
end
end
end
end
Then include the Module in BaseRole
# /models/base_role.rb
class BaseRole < ActiveRecord::Base
include AssignableBaseRole
belongs_to :role
belongs_to :role_type
......
......
end
Then in my spec:
it "adds correct authority for creator role" do
create_assignment
base_role = BaseRole.creator_for_account # <== NoMethodError here
user1 = Factory.create(:user)
account.users << user1
user1.roles_for_assignable(account).should include(base_role.role)
end
Did you have another class in your project or specs with the same name, but doesn't have the dynamic methods added? I had the exact same problem as you, and renaming one of the classes fixed it.
My guess is the other class is getting loaded first
It appears you are defining these methods based on values in the database:
BaseRole.all.each do |base_role|
.....
Could it be that "creator" doesn't exist in the test database as a role type, or "account" doesn't exist as assignable_type?
Presumably you are testing this in the console for development, not test, so the data could be mismatched. Might need to set up the data in a before hook.
I'm working on this project for a class and one of the requirements is "Validation on the date field type".
For example, I did:
rails g scaffold Tasks id:primary_key description:string due:date
What would I add to the model so I can validate the date?
I've tried multiple different "solutions" and nothing seems to be working.
In your model, you can define a custom method to handle your validations.
class Task < ActiveRecord::Base
validate :check_due_date
def check_due_date
# You can now check the "due" field here. For example, if you only want to allow due
# dates today and later:
if due < Date.today
errors.add(:due, "can only be today or later.")
end
end
end
You could use the simple "validates timeliness" plugin: https://github.com/adzap/validates_timeliness/
Then use the following syntax:
class Task < ActiveRecord::Base
validates_date :due
end
Unless plugins aren't allowed, in which case the other answer (creating your own validator) would be more suitable.