I have 2 classes, ProductDetails and ProductStatus.
class ProductDetail < ActiveRecord::Base
belongs_to :product_status
end
and
class ProductStatus < ActiveRecord::Base
has_many :product_details
end
The schema for these tables is the following:
create_table "product_details", force: :cascade do |t|
t.integer "product_id", limit: 4
t.string "serial", limit: 255
t.string "comment", limit: 255
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "status", limit: 4
end
create_table "product_statuses", force: :cascade do |t|
t.boolean "available"
t.string "name", limit: 255
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
Showing the ProductDetails, I have the status_id, but I want to display the name. It's in product_statuses as name.
I tried this:
<% #product_details.each do |product_detail| %>
<td><%= product_detail.product_status.name %></td>
<% end %>
But It doesn't work :(
Need help.
Thanks!
From your comments I realized you're trying to use the column status as foreign key. This has to be mentioned in the belongs_to statement:
belongs_to :product_status, foreign_key: :status
By default, rails is looking for a column named product_status_id as foreign key.
See also http://guides.rubyonrails.org/association_basics.html#options-for-belongs-to-foreign-key
Related
I want to fetch sku_code from products, wh_name from warehouses table and item_count from product_warehouses.
I tried something like
Product.all.includes(:product_warehouses)
But not working :(
Below are the schema of my tables
create_table "product_warehouses", force: :cascade do |t|
t.integer "product_id"
t.integer "warehouse_id"
t.integer "item_count"
t.integer "threshold"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["product_id"], name: "index_product_warehouses_on_product_id"
t.index ["warehouse_id"], name: "index_product_warehouses_on_warehouse_id"
end
create_table "products", force: :cascade do |t|
t.string "sku_code"
t.string "name"
t.decimal "price"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "warehouses", force: :cascade do |t|
t.string "wh_code"
t.string "wh_name"
t.string "pin"
t.integer "max_cap"
t.integer "threshold"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
Below are the relationship between tables:
class Product < ApplicationRecord
has_many :product_warehouses
has_many :warehouses, through: :product_warehouses
end
class ProductWarehouse < ApplicationRecord
belongs_to :product
belongs_to :warehouse
end
class Warehouse < ApplicationRecord
has_many :product_warehouses
has_many :products, through: :product_warehouses
end
If you want to load all three records with a single query, use eager_load:
Product.all.eager_load(:product_warehouses, :warehouses)
Let's say you want to print sku_code, wh_name, and item_count in the console. First load all the products into variable:
products = Product.all.eager_load(:product_warehouses, :warehouses)
Then loop through the records and print out each of the values:
products.each do |product|
puts "sku_code: #{product.sku_code}"
product.product_warehouses.each do |product_warehouse|
puts "item_count: #{product_warehouse.item_count}"
puts "wh_code: #{product_warehouse.warehouse.wh_code}"
end
end
I have a problem, I want to create an hashtags system, but when I run my code, and when I want to create a travel that contain hashtags I have this error :
ActiveRecord::StatementInvalid in TravelsController#create
Could not find table 'tags_travels'
Here is my travel.rb
class Travel < ApplicationRecord
has_many :posts
belongs_to :user
has_and_belongs_to_many :tags
#after / before create
after_create do
travel = Travel.find_by(id: self.id)
sh = self.hashtags.scan(/#\w+/)
sh.uniq.map do |s|
tag = Tag.find_or_create_by(name: s.downcase.delete('#'))
travel.tags << tag
end
end
before_update do
travel = Travel.find_by(id: self.id)
travel.tags.clear
sh = self.hashtags.scan(/#\w+/)
sh.uniq.map do |s|
tag = Tag.find_or_create_by(name: s.downcase.delete('#'))
travel.tags << tag
end
end
end
my tag.rb
class Tag < ApplicationRecord
has_and_belongs_to_many :travels
end
the schema.rb file (just table concerned) :
create_table "tags", force: :cascade do |t|
t.string "name"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "topics", force: :cascade do |t|
t.string "title"
t.string "text"
t.string "end_date"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "post_id"
end
create_table "travels", force: :cascade do |t|
t.string "name"
t.string "trip_type"
t.string "description"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "user_id"
t.string "hashtags"
end
create_table "travels_tags", id: false, force: :cascade do |t|
t.integer "travel_id"
t.integer "tag_id"
t.index ["tag_id"], name: "index_travels_tags_on_tag_id"
t.index
["travel_id"], name: "index_travels_tags_on_travel_id"
end
Someone has a solution ? Thank !
Rails looks for join tables in a specific syntax. Its trying to find tags_travles but uouve created it with travels_tags.
Change your model associations to specify the join table.
has_and_belongs_to_many :travels, :join_table => :travels_tags
And
has_and_belongs_to_many :tags, :join_table => :travels_tags
Heres some info from the docs to help explain the defsult behaviour for join table naming.
"By default, the name of the join table comes from the union of the first two arguments provided to create_join_table, in alphabetical order."
http://edgeguides.rubyonrails.org/active_record_migrations.html#creating-a-join-table
I am relatively new to RoR.
This works nicely:
<td><%= collection_select :competitions_members, :member_id, Member.all, :id, :first_name %></td>
This one picks no value (actually all such calls to tables with translations):
<td><%= collection_select :competitions_members, :tull_id, Tull.all, :id, :name %></td>
seeded data in competitions_members table
Member can be involved in many competition. Basically I have N:M relationship between members and competitions via competitions_members table.
Tull is a dictionary. Value to be set during the process of assigning members to a competition.
Data model classes:
class Member < ApplicationRecord
has_and_belongs_to_many :competitions
end
class Competition < ApplicationRecord
has_and_belongs_to_many :members
end
class CompetitionsMember < ApplicationRecord
end
Tull table has also translations in separate table.
class Tull < ApplicationRecord
translates :name
has_many :competitions_members
# separate different localizations of the record
def cache_key
super + '-' + Globalize.locale.to_s
end
end
Relevant schema.db excerpt
create_table "members", force: :cascade do |t|
t.string "first_name"
t.string "last_name"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "competitions", force: :cascade do |t|
t.string "name"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "competitions_members", force: :cascade do |t|
t.integer "member_id"
t.integer "competition_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "tull_id"
t.index ["tull_id"], name: "index_competitions_members_on_tull_id"
end
create_table "tull_translations", force: :cascade do |t|
t.integer "tull_id", null: false
t.string "locale", null: false
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "name"
t.index ["locale"], name: "index_tull_translations_on_locale"
t.index ["tull_id"], name: "index_tull_translations_on_tull_id"
end
create_table "tulls", force: :cascade do |t|
t.string "name"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
Any help apreciated. I just realized this might be connected with translated tables somehow.
class Tull < ApplicationRecord
has_many :translations
translates :name, :fallbacks_for_empty_translations => true
attr_accessible :translations_attributes
end
Try to execute below code in rails console:
Tull.first.translations - If this gives you translation records that means the associations are correct.
Now check at view side, how would you generate attributes for multilingual stuffs. I would suggest to use globalize_accessors.
Please send me the codebase.
I'm using Chartkick in my RoR app and I'm trying to create a pie chart that displays all the People that are in each Group. My Group and Person model are both HABTM. Right now the chart is working and only displaying number of groups(screenshot and code below) if someone knows how to grab the number of people in each group using active record I'd love it!
here is my code
<%= pie_chart Group.group(:name).count %>
Here is a screenshot
here is my Schema
create_table "people", force: :cascade do |t|
t.string "phone_number"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.boolean "subscribed", default: true, null: false
t.string "city"
t.string "state"
t.string "zip"
t.string "country"
end
create_table "groups", force: :cascade do |t|
t.string "name"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "groups_people", id: false, force: :cascade do |t|
t.integer "group_id", null: false
t.integer "person_id", null: false
end
here is the person model
class Person < ActiveRecord::Base
has_many :deliveries
has_and_belongs_to_many :groups
here is group model
class Group < ActiveRecord::Base
has_and_belongs_to_many :people
has_and_belongs_to_many :messages
end
<%= pie_chart Group.includes(:people).all.map {|g| [g.name, g.people.size] }.to_h %>
By the way, it will better to move this logic into model body.
I'm rails begginer.
how to load database that has following condition.
I want show lecture list that has order by comment.created_at DESC
schema.rb
create_table "comments", force: :cascade do |t|
t.text "content"
t.integer "user_id"
t.integer "lecture_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "likedcount", default: 0
end
create_table "lectures", force: :cascade do |t|
t.string "subject"
t.string "professor"
t.string "major"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "uptachi", default: 0
t.integer "hatachi", default: 0
end
lecture.rb
has_many :comments
comment.rb
belongs_to: lectures
You need to write it as:
has_many :comments, -> { order("comments.created_at DESC") }
As per the OP's comment, it seems, what he want is a named scope. Like,
scope :order_by_comments, -> { joins(:comments).order("comments.created_at DESC") }