Create a reference column for 2 existing models in rails 3 - ruby

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

Related

Ruby On Rails - new migration and model change causing migration failure

I've created a new migration to add a new table. Lets call it
new_items which creates a new table.
in the migration, i've specified that the relationship with another table
t.belongs_to :parent
In my model,
class NewItem < ApplicationRecord
belongs_to :parent
class Parent < ApplicationRecord
has_many :new_items, :dependent => :destroy
So when I run all migration from scratch, there is a failure on an older migration
"could not find table 'new_items'"
in the failed migration, this is the line that where the problem lies
def up
Parent.where(name: "TestName").destroy_all
end
there is something wrong with my Parent model, as when i remove this following line it runs to completion
has_many :new_items, :dependent => :destroy
I know the issue is with the relationship between Parent and NewItem, but not sure how its best fixed
I can kinda see why its happening, but not sure how to resolve it while still keeping the relationship between the tables
Whenever using your ActiveRecord models in migrations, it is wise to define them within these migrations, so any changes to your models in the future won't break old migrations.
class Parent < ApplicationRecord; end
or in a nicer way, if your class does not need to do anything
Parent = Class.new(ApplicationRecord)
added inside your migration class should fix your issue.
Side note: if you simply want to delete all the records from parents table, it would be better to call to call Parent.delete_all in your migration. This would also solve the issue, but adding models to migrations is good practice.
You should not use ActiveRecord models in the migration. ActiveRecord doesn't like when Ruby class and schema doesn't match. And it can happens if multiple migration need to be run.
I suggest to only use SQL queries in migration.
def up
execute <<-SQL
DELETE FROM parent WHERE name = "TestName";
SQL
end

How do I declare model attributes in Rails 4?

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.

How does a Rails fixture find its model class?

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.

How do you add new column named "unique_id", and associate mailboxer with devise?

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.

Active Admin and STI model error: Could not find table 'categories'

Update #1: Solved! Somehow Pow did not restart it's processes, so after updates it was loading the old config files. And it was loading the wrong locale file.
I deleted gems I installed recently (only from Gemfile) and restarted Pow. Then one by one I added gems back to the Gemfile. As well ActiveAdmin as Rails localization started working normally.
Original question:
I am trying to setup ActiveAdmin to support my taxonomies. My setup is as following:
class Taxonomy < ActiveRecord::Base
end
class Category < Taxonomy
has_ancestry # implements a tree of categories
end
class Tag < Taxonomy
end
So now I added the following to ActiveAdmin:
ActiveAdmin.register Category do
end
And it returns the folioing error:
Could not find table 'categories'
My migrations were definitely ran. And I have some valid STI records in the taxonomies table. So what can be wrong?

Resources