I plan on making a genotype calculator in the future. I intend for this calculator to eventually be able to compute the following from a pairing: probability of color listing all possibilities, genotype.
I am wanting to make a dropdown menu/text field combination on a very simple webpage to learn how it works so that I can continue my project and hopefully meet this goal. I have searched and tried to figure this out, but I am pretty lost. Currently in my database I have a table called "colors" with the following schema:
id
angora_color
genotype
created_at
updated_at
I do not intend for users to be able to add data to this form. I want them to be able to select a color from the dropdown box, and get the genotype in a text field below it.
My code so far is as follows:
class Color < ActiveRecord::Base
has_one :genotype
end
class Genotype < ActiveRecord::Base
has_one :color
end
index.html.erb:
<h2>Placeholder for Genotype List..</h2>
class PagesController < ApplicationController
def index
end
end
I appreciate any help.
Are you sure you only want a has_one relationship? Wouldn't a Genotype have many colors? and Colors can be part of many Genotypes?
You also can't have both models declare has_one. One model has to belong to the other. And the one that belongs_to should have the foreign key as <model_name>_id e.g. genotype_id. In your table you only put genotype. Rails looks for that _id.
What may be better here is to use has_many through. Create a join model such as genotypes_colors:
rails g model GenotypesColor genotype_id:integer color_id:integer
Then change your code to look like:
class Genotype < ActiveRecord::Base
has_many :genotypes_colors
has_many :colors, through: :genotypes_colors
end
class GenotypesColor < ActiveRecord::Base
belongs_to :genotype
belongs_to :color
end
class Color < ActiveRecord::Base
has_many :genotypes_colors
has_many :genotypes, through: :genotypes_colors
end
Now you can correctly relate a Genotype to its Colors. You can use fields_for in either model's forms to create the genotypes_color association that will relate a Genotype to any Color or vice versa. If this sounds about right let me know and I can further help on how to do the forms.
Right now my migration reads as follows:
class CreateColors < ActiveRecord::Migration
def change
create_table :colors do |t|
t.string :angora_color
t.string :genotype
t.timestamps
end
end
end
Related
I have the following class:
class Blog < ApplicationRecord
enum platform: {
wordpress: 'wordpress',
drupal: 'drupal',
}
has_many :wordpress_posts
has_many :drupal_posts
end
Besides platform, it also holds things like url and category. It also has a relationship of has many with WordPressPost and DrupalPost:
class WordPressPost < ApplicationRecord
belong_to :blog
end
class DrupalPost < ApplicationRecord
belongs_to :blog
end
I would like to know, if it's possible to infere what has_many relationship should be the valid, depending on the platform value: if the platform value is wordpress, the blog should only contain relationships with wordpress post entities. I'm not sure if there is a Rails way to solve it. I would love if someone can help me and show me the proper Rails way of implement such data model.
Thanks
Your idea of using a enum won't work here since assocations are class level and the value of the enum is only known on the instance level.
If you really wanted to use an enum you could hack something together with an instance method but it won't really behave like an assocation when it comes to stuff like eager loading:
class Blog < ApplicationRecord
# ...
def posts
send("#{platform}_posts")
end
end
What you can do is use Single Table Inheritance to setup classes that share a table yet have different behavior.
First add a type column to the table:
class AddDetailsToBlogs < ActiveRecord::Migration[6.0]
def change
change_table :blogs do |t|
t.remove :platform
t.string :type, index: true, null: false
end
end
end
If you have existing data you should go through it and set the type column based on the value of platform before you drop platform and make type non-nullable.
Then setup the subclasses:
class Blog < ApplicationRecord
# shared behavior
end
class WordPressBlog < Blog
has_many :posts,
class_name: 'WordPressPost',
foreign_key: :blog_id,
inverse_of: :blog
end
class DrupalBlog < Blog
has_many :posts,
class_name: 'DrupalPost',
foreign_key: :blog_id,
inverse_of: :blog
end
The main advantage of STI is that it lets you query as a single table and thus treat it as a homogenous collection, the drawbacks are that you are potentially wasting database space with columns containing largely nulls and it can become quite unweildy if the types differ to much from each other.
Im not sure i understand rails polymorphic.
In Java you can create Objects from the same Objecttype:
http://www.fh-kl.de/~guenter.biehl/lehrgebiete/java2/j2-08-Dateien/abb.8.10.jpg
Person trainer = new Trainer()
Person sportler = new Trainer()
In Rails http://guides.rubyonrails.org/association_basics.html#polymorphic-associations:
In this example: picture can be from an employee or from a product, sounds strange because this is not realy the same type.
Do i understand the real purpose: to save objects in the same container an array of person or image?
In my rails project: I have several person: sportsmen, trainer and guest. They are sons of person (inheritance).
I think i meet the inheritance reason.
There is another class named exercise.
Sportsmen and trainer can create exercises.
So i want to use polymorphic. Exercises can be from trainer or sportsmen. Like in the example of the rails page, images can be from employee or a product.
Do i meet the best practise?
How do i implement a has_many :through with polymorphy?
It is not possible to use a habtm assoziation with polymorphic.
You have to define a additional class, but how exactly?
I think you want single table inheritance (STI) models, not a polymorphic relationship.
See this article http://www.alexreisner.com/code/single-table-inheritance-in-rails and these stackoverflow answers Rails - Single Table Inheritance or not for Applicant/Employee relationship Alternative to Rails Single Table Inheritance (STI)?
Just to make it clear, you should use polymorphic associations when you have a model that may belong to many different models on a single association.
Suppose, you want to be able to write comments for users and stories. You want both models to be commendable. Here's how this could be declared:
class Comment < ApplicationRecord
belongs_to :commentable, polymorphic: true
end
class Employee < ApplicationRecord
has_many :comment, as: :commentable
end
class Product < ApplicationRecord
has_many :comment, as: :commentable
end
To declare the polymorphic interface (commendable) you need to declare both a foreign key column and a type column in the model.
class CreateComments < ActiveRecord::Migration
def change
create_table :comments do |t|
t.text :body
t.integer :commentable_id
t.string :commentable_type
t.timestamps
end
add_index :comments, :commentable_id
end
end
You can check more details about associations here.
I am learning Rails and ActiveRecord stuff but I am kind of stuck on this small problem.
Lets say you I a product (Stock) and every product has a colour, normally the right way is to setup an association. Please take a look at the below code:
class Stock < ActiveRecord::Base
attr_accessible :size, :colour_id
end
class Colours < ActiveRecord::Base
belongs_to :stock
end
Actually what I want to be able to do is
p #stock_item.colour.name
# But I get this error
SQLite3::SQLException: no such column: colours.stock_id: SELECT "colours".* FROM "colours" WHERE "colours"."stock_id" = 1 LIMIT 1
When in fact the query should have been:
SELECT "colours".* FROM "colours" WHERE "colours"."id" = "stock"."colour_id"
As colours are all unique in reality a property of the Stock item. How can I setup an association this way so that I could do:
p #stock_item.colour.name
> Red
Thanks.
Umer
you need to add a belongs_to association to stock and not to colour since stock has the colour_id
class Stock < ActiveRecord::Base
belongs_to :colour
end
and you most probably want a has_many association on colour
class Colour < ActiveRecord::Base
has_many :stocks
end
Hey guys. I'm trying to build this Picture Battle site, (where you chose the picture you prefer) and I had two models. Pictures, and Battles.
So Each Picture has_many Battles, but Each Battle belongs to two pictures. How do I associate it.. I was thinking something like "belongs_to_many" but apparently that doesn't exist.
from what i see this could be easily done by using a has_and_belongs_to_many association
You should set up a has_many :through relationship if you need to work with the relationship model as an independent entity. If you don’t need to do anything with the relationship model, which is probably the case, it may be simpler to set up a has_and_belongs_to_many relationship
here's how you do the HABTM:
class Picture < ActiveRecord::Base
has_and_belongs_to_many :battles
end
and
class Battle < ActiveRecord::Base
has_and_belongs_to_many :pictures
end
then you can call picture.battles and battle.pictures
you will also need to create a new migration that looks like this
class CreateBattlesPicturesJoinTable < ActiveRecord::Migration
def self.up
create_table :battles_pictures, :id => false do |t|
t.integer :battle_id
t.integer :picture_id
end
end
def self.down
drop_table :battles_pictures
end
end
more info here
It is a many-to-many association. You can achieve it through a join model. Check has_many in the API docs
I am developing an application like the stackoverflow, which questions or articles have at less one tag. And one tags must have one or more articles.
So, I am doing this in migration in RoR. I am consider which relationship is suitable for both table. In article table, should use a "has_many", and in the tag table, should use "has_many".
But I am thinking is it necessary to add one more table in the middle, something like....
So, the first one is like that:
class Article < ActiveRecord::Base
has_many :tags
end
class Tag < ActiveRecord::Base
has_many :articles
end
or something like this:
class Article < ActiveRecord::Base
has_many :articleTagList
has_many :tags, :through => : articleTagLists
end
class Tag < ActiveRecord::Base
has_many :articleTagList
has_many :articles, :through => :articleTagLists
end
class ArticleTagList < ActiveRecord::Base
belongs_to :article
belongs_to :tag
end
Many-to-Many relationships in a normalized database will always need a third "look-up table."
If you denormalize you can get away with just having the tag id's in one field with a delimiter between them. But you also have to provide the logic to handle retrieval.
I'd personally just go with the normalized option.
If you don't want to store any information on the middle table (for example the name of the user who added tag X to the question Y), you can use the has_and_belongs_to_many:
http://apidock.com/rails/ActiveRecord/Associations/ClassMethods/has_and_belongs_to_many
If you want to store something, you need to create the middle model, as your example. In your example, the ArticleTagList model should be called ArticlesTag and the database table should be articles_tags, by convention.