Ruby on Rails - Create a Relationship Table - ruby-on-rails

I am RoR noob so this might be a simple problem for someone. I have created two models - User and Feedback and I have two tables associated with them. users and feedbacks.
Now I want to create a relationship table with user_id as one column and feeback_id as the other column.
Do I create a model or just a migration? I am confused.
Here are my user and feedback migrations.
class CreateUsers < ActiveRecord::Migration
def self.up
create_table :users do |t|
t.string "first_name"
t.string "last_name"
t.string "email"
t.string "phone"
t.string "password_hashed"
t.string "password_salt"
t.boolean "isdeleted", :default => false
t.timestamps
end
end
def self.down
drop_table :users
end
end
class CreateFeedbacks < ActiveRecord::Migration
def self.up
create_table :feedbacks do |t|
t.text "feedback"
t.integer "rating"
t.boolean "isdeleted", :default => false
t.timestamps
end
end
def self.down
drop_table :feedbacks
end
end
Now do I create a model??? >rails generate model FeedbackUserJoinTable ? Or just a migration like this ??
class CreateFeedbackUserJoinTable < ActiveRecord::Migration
def change
create_table :feedbacks_users, :id => false do |t|
t.integer :feedback_id
t.integer :user_id
end
end
end

I like this answer to another SO question on has_and_belongs_to_many. Basically use HABTM relationships if the relationships between users and feedbacks will remain simple.
If you foresee that these relationships won't remain simple, you should create a join model between the two and use has_many ..., :through => .... That way, when you want to add properties to the relationships between a particular pair of User and Feedback objects, you can define those properties on the join model.

You do not need to create a model. Just create the migration as you have written :)

Related

Association one column in model to another model

Hello i have to model like;
class CreateLecturers < ActiveRecord::Migration
def change
create_table :lecturers do |t|
t.string :firstname
t.string :lastname
t.string :position
t.string :email
t.timestamps null: false
end
end
end
and here is my second model.
class CreateCurriculums < ActiveRecord::Migration
def change
create_table :curriculums do |t|
t.string :title
t.integer :hours
t.integer :year
t.text :description
t.timestamps null: false
end
end
end
I want migrate to Curriculums to Lecturer. But not with id, with title
how it's can be possible?
So i use rails-admin. When i add some Curriculum i want to choose with dropdown lecturer and when i add some Lecturer i want to choose Curriculum between models .
No matter what, you have to have association between two models. Also do not forget to add curriculum_id to lectures table.
curriculum.rb
has_many :lectures
lecture.rb
belongs_to :curriculum
To add migration
rails g migration add_curriculum_id_to_lectures curriculum_id:integer

How To add new table and link it with previous table in with adding index in ruby

I have this table structure:
class CreateUsers < ActiveRecord::Migration
def change
create_table :users do |t|
t.string :username
t.string :email
t.string :encrypted_password
t.string :salt
t.timestamps
end
end
end
And I want to add a new table as shown below:
class CreateHolidays < ActiveRecord::Migration
def change
create_table :holidays do |t|
t.string :earn_leave
t.string :seek_leave
t.string :unplanned_leave
t.timestamps
t.timestamps
end
add_index(users,id)
end
end
What should I do for this, please also suggest commands that can/should be used for migration.
You want to look up about foreign_keys:
#app/models/holiday.rb
class Holiday < ActiveRecord::Base
belongs_to :user
end
#app/models/user.rb
class User < ActiveRecord::Base
has_many :holidays
end
This will mean you have to add the user_id foreign key to your holidays data table:
class CreateHolidays < ActiveRecord::Migration
def change
create_table :holidays do |t|
t.references :user
t.string :earn_leave
t.string :seek_leave
t.string :unplanned_leave
t.timestamps
t.timestamps
end
end
end
You must remember that Rails is designed to be built on top of a relational database. As such, it uses foreign_keys in the tables to locate associated records:
The above will allow you to call:
#user.holidays
and
#holiday.user

Cannot find table 'noticia'

I created this table called noticias
class CreateNoticia < ActiveRecord::Migration
def change
create_table :noticias do |t|
t.string :titulo
t.date :data
t.text :sumario
t.text :texto
t.boolean :destaque
t.boolean :ativa
t.timestamps
end
end
end
and of course I created the model
class Noticia < ActiveRecord::Base
#validations
end
and when I try to create a Noticia it throws:
cannot find table 'noticia' so far I've been creating the models with the rails generate model command and it has all worked out. But now this happens. I don't understand.
Does someone know what's happening?
noticia seems to be plural form of noticium, so:
ActiveSupport::Inflector.pluralize('noticia')
# => "noticia"
That's why Rails expect noticia table.

Polymorphic Association and extra id field

I need some help with polymorphic associations. Below is my structure:
class Category < ActiveRecord::Base
has_ancestry
has_many :categorisations
end
class Categorisation < ActiveRecord::Base
belongs_to :category
belongs_to :categorisable, polymorphic: true
end
class classifiedAd < ActiveRecord::Base
belongs_to :user
has_one :categorisation, as: :categorisable
end
And here is my schema.rb
create_table "classifiedads", force: true do |t|
t.string "title"
t.text "body"
t.decimal "price"
t.integer "user_id"
t.datetime "created_at"
t.datetime "updated_at"
end
add_index "classifiedads", ["user_id"], name: "index_classifiedads_on_user_id", using: :btree
create_table "categories", force: true do |t|
t.string "name"
t.string "ancestry"
t.datetime "created_at"
t.datetime "updated_at"
end
add_index "categories", ["ancestry"], name: "index_categories_on_ancestry", using: :btree
create_table "categorisations", force: true do |t|
t.integer "category_id"
t.integer "categorisable_id"
t.string "categorisable_type"
t.datetime "created_at"
t.datetime "updated_at"
end
It seems like the associations is correct as when I'm in the console I can do the appropriate commands and all seems to return the right results, for example: Category.first.categorisations or ClassifedAd.first.categorisation. But what I don't understand is saving the association from the Create and editing the record via the Update actions. I'm using simple_form to create my forms and when looking at the params I get the below:
{"title"=>"Tiger",
"body"=>"Huge Helicopter",
"price"=>"550.0",
"categorisation"=>"5"}
and this fails to update or even create as I get this error : Categorisation(#70249667986640) expected, got String(#70249634794540) My controller actions code are below:
def create
#classified = Classifiedad.new(classifiedad_params)
#classified.user = current_user
#classified.save
end
def update
#classified.update(classifiedad_params)
end
def classifiedad_params
params.require(:classifiedad).permit(:title, :body, :price)
end
I think it has something to do with the params as categorisation should be within a sub hash of results, is this right? Also, I need to do something extra within the actions, but what? What the params[:categorisation] value needs to do is save the number into the Categorisations.category_id table column and also save the polymorphic association. This table will be used across other models, which will also be a has_one association, as the user will only be able to select one category for each record. I really hope someone can help me here as the more I look into it the more I get confused :S Please let me know if you ned anymore info from me.
I'm using Rails 4 and Ruby 2
EDIT 2
I managed to get something working but I'm still not sure if its right. Below is the update code for the Create and Update actions. Would be good to know if there is a better way of doing this?
def create
#classified = Classifiedad.new(classifiedad_params)
#classified.user = current_user
**** NEW
cat = Categorisation.new(category_id: params[:classified][:categorisation])
#classified.categorisation = cat
**** END NEW
#classified.save
end
def update
**** NEW
#classified.categorisation.update_attribute(:category_id, params[:classified][:categorisation])
**** END NEW
#classified.update(classifiedad_params)
end

Is this the correct way to set up has many with multiple associations?

I'm trying to set up a new project for a music site. I'm learning ROR and am a bit confused about how to make join models/tables. Does this look right?
I have users, playlists, songs, and comments. Users can have multiple playlists. Users can have multiple comments on their profile. Playlists can have multiple songs. Playlists can have comments. Songs can have comments.
class CreateTables < ActiveRecord::Migration
def self.up
create_table :users do |t|
t.string :login
t.string :email
t.string :firstname
t.string :lastname
t.timestamps
end
create_table :playlists do |t|
t.string :title
t.text :description
t.timestamps
end
create_table :songs do |t|
t.string :title
t.string :artist
t.string :album
t.integer :duration
t.string :image
t.string :source
t.timestamps
end
create_table :comments do |t|
t.string :title
t.text :body
t.timestamps
end
create_table :users_playlists do |t|
t.integer :user_id
t.integer :playlist_id
t.timestamps
end
create_table :playlists_songs do |t|
t.integer :playlist_id
t.integer :song_id
t.integer :position
t.timestamps
end
create_table :users_comments do |t|
t.integer :user_id
t.integer :comment_id
t.timestamps
end
create_table :playlists_comments do |t|
t.integer :playlist_id
t.integer :comment_id
t.timestamps
end
create_table :songs_comments do |t|
t.integer :song_id
t.integer :comment_id
t.timestamps
end
end
def self.down
drop_table :users
drop_table :playlists
drop_table :songs
drop_table :comments
drop_table :users_playlists
drop_table :users_comments
drop_table :playlists_comments
drop_table :songs_comments
end
end
Few things:
Short version:
Join tables should be alphabetical (e.g. create_table :comments_users
This is only one half of setting up your associations. I'd like to see your model code as well
Your comments model should be setup to be a polymorphic association to the others.
Long version:
When setting up a join table (e.g. users and comments) you want to make it alphabetical. So that the users/comments table is actually create_table :comments_users. Ideally, you would want to setup a more meaningful name for this join table (since it is a model - see below) but it's your call.
Remember that you have to create models for these :has_many through associations. Most of these join tables could be created with :has_and_belongs_to_many but for future expansions, may as well use the :has_many through method. It would be wise to provide your association code in your model files as well - just as important as the creation of tables.
For comments, think about polymorphic relationships. This is because the comments are the same across all the different tables it belongs to. What this does is look for a type column in the polymorphic join table and that tells it what table the record (i.e. comment) belongs to.
Starting Resources:
Check out Ryan's brilliant (as usual) Railscast on the subject:
http://railscasts.com/episodes/47-two-many-to-many
Also, on polymorphism:
http://railscasts.com/episodes/154-polymorphic-association
http://guides.rubyonrails.org/association_basics.html
That looks ok. You seem to have the ID's in all the right place.
Couple of points though:
It's often easier to have many small migrations. I generally create each model and migration individually. You can then start building your model relationships in lock-step with your tests to ensure that your business requirements are actually being implemented.
You have some tests, right? :)

Resources