I've created a model that changes its table name, and now the fixture doesn't seem to be able to find it. Is there something I need to do to tell the fixture which model to use?
I'm using Rails 2.0.5.
The symptom is that when I run rake db:fixtures:load, I get an error that the id field cannot be null.
It's weird, because I have another model that is changing its table name, and it works fine.
I have two tables: customer and long_prefix_orders. They both have required id fields.
I have two models that look something like this:
# app/models/customer.rb
class Customer < ActiveRecord::Base
set_table_name :customer
end
# app/models/order.rb
class Order < ActiveRecord::Base
set_table_name :long_prefix_orders
end
I have two fixtures that look something like this:
# test/fixtures/customer.yml
one:
name: Bob
# test/fixtures/long_prefix_orders.yml
one:
name: Party Supplies
customer_id: one
The customer fixture works, and the order fixture doesn't. Is changing the table name from plural to singular a small enough change that the fixture can find it, or is there some other configuration that I've forgotten about?
I think the problem here was that I was using customer_id instead of customer when I referred to the parent record. Use the name of the relationship in fixtures, not the name of the database field.
Related
I am trying to understand Rails and I dont understand how I declare the model attributes correctly. For now my user class is looking like this:
class User < ActiveRecord::Base
has_many :users # Friends
end
By Googling I have understand that before Rails 4 one could determine attributes with the attr_accessible, like this:
attr_accessible :firstname, :lastname, :age, :sex
But this seems to be deprecated, how can I do that same thing in Rails 4?
has_many :users is not a model attribute, its model association. It means model User can have many User objects, which is incorrect. (also does not make sense even literally)
What attr_accessible does?
Specifies a white list of model attributes that can be set via
mass-assignmen
To add attributes to a model, you need to generate migrations.
Example, lets add name attribute to users:
rails generate migration AddNameToUsers #creates a migration file to add `name` column to `users` table
followed by:
rake db:migrate # executes migration file creating `name` column in `users` table
Now you can access these attributes simply as:
user = User.new
user.name
Again, if you want to mass-assign this attribute at some point of your code, you will need to specify this in your class with attr_accessible, as in your original example.
I am doing Rails 3.2.3 and have an issue:
I have 2 models Product and User already. The User table was created when I setup devise. I want to make product belong to user and here is what I did:
rails g migration AddUserToProduct user_id:integer
In product model, I add:
belongs_to :user
In User model, I add:
has_many :products
I ran
rake db:migrate
and i looks fine. To test that, I go to the web interface, log in and make a new product then using Rails console, I type in
Product.last
I am confused since user_id:nil which means there's no reference between the user and the product.
Is there anything wrong with my code ? What is the proper way to create a reference column between two existing Models ?
Thanks for your helps
Could you show your Products controller? Most likely, you have something like
def create
#product = Product.new(params[:product])
...
end
if so, change it to
def create
#product = current_user.products.build(params[:product])
...
end
How do you create routes for models that have option child properties? Say I am creating a help desk app, and the ticket could be associated with an order that the customer had previously had with me, or it could be regarding an item in the catalog they have not yet ordered.
class CustomerServiceTicket
belongs_to :order
belongs_to :item
belongs_to :buyer
belongs_to :customer_service_category
end
class Order
...
has_one :customer_service_ticket
...
end
class Item
...
has_one :customer_service_ticket
...
end
in the schema for customer_service_ticket, order_id and item_id are nullable.
So I'll have a 'create a customer service ticket' link next to their say their order_id's on the their closed orders page...and a similar link next to the item_id on the product catalog page.
I'm thinking the url structure should look like this:
customer_service_ticket/new/order/123
for tickets created relating to an order
and
customer_service_ticket/new/item/789
for tickets created relating to an item
and just
customer_service_ticket/new
when there is neither (also valid for cases where the customer just has a general question)
How would I structure the routes to be the most efficient? I'm not married to that URL structure above, if there is a better way I'm happy to try it.
Based on how you describe your routes, it sounds like the orders and items already exist at the time you need to create a new customer service ticket, is that correct? If so, then it would be better to create your routes like this:
orders/123/customer_service_ticket/new
items/123/customer_service_ticket/new
customer_service_tickets/new
Any time you are adding a resource onto an existing resource, the new resource typically goes at the end, with the action you are performing being the last portion of the URL. To create this structure it would be something like this:
resources :orders do
resource :customer_service_ticket
end
resources :items do
resource :customer_service_ticket
end
resources :customer_service_ticket
However, you may also want to rethink your relationships. Once a customer service is closed for an order/item, are you certain there will never be another customer service ticket relating to that order/item? That may indicate a has_many relationship. You may also want to look into a polymorphic relationship for orders and items to customer service tickets. That way if you want to add more entities that can relate to customer service tickets, you don't have to keep adding database fields. Note that changing to a has_many would change the routes declarations above slightly.
In a ruby script I am running a loop in which I am dynamically getting a table name from a list of tables and have to perform some sort of CRUD operation (mainly insertion) on it.
I am using Sequel Orm and have created models for the various tables.
How do I find the name of the Model for each table so that I can perform the insertion?
tables=["table1","table2",'table3",...]
tables.each do |t|
#perform insertion on t
#how to find the model name for table t?
end
I can use a hash to store the model names for each table or can follow a pattern like converting the first character of each table to uppercase or something like that.
Is there a better way to do this?
What you are asking is not possible in the general case without a brute force search, and even then it is ambiguous, for the simple reason that the following is valid:
class Foo < Sequel::Model(:table1); end
class Bar < Sequel::Model(:table1); end
Basically, each model has a related dataset (usually just a simple SELECT * FROM table). However, other models can use the same or similar dataset. So going from model to table is simple, but table to model is not.
If you've created your own models, the easiest way to handle what you want is to use a hash:
ModelMap = {}
ModelMap["table1"] = Model1
ModelMap["table2"] = Model2
Then you can just do:
ModelMap[t]
inside that each block to get the model class.
One way to get the model name from the table name, as long as pluralization conventions have been followed between your models and tables, is something like:
table_name = :users
table_name.to_s.classify
However it doesn't look like that's what you're trying to do. You need to insert new or update existing reords. Since you already have the table name, you may wish to consider doing something like:
tables=["table1","table2",'table3",...]
tables.each do |t|
DB[t.to_sym].insert(...)
end
However you may wish to consider that Jeremy Evans, whose answer is above, is the creator of the Sequel gem and if he didn't recommend this as a solution then there may be a good reason.
I am working with a database that is already in place and used by other applications.
The people who designed the database did not use pluralized table names, so DataMapper chooses the wrong table name when following associations.
For instance:
class Foo
has n :components # => the table name here should be COMPONENT, but datamapper uses COMPONENTS
end
How do I change this behavior?
Change the name on the model itself.
class Component
# ...
storage_names[:default] = 'component'
end