I have a question about reaching across multiple association levels, if anyone could help me out?
I have a warehouse, and I'm trying to call up an inventory of products by their tag numbers. So far I can through and use methods defined in the Tag model, and grab associated Product name attributes easily enough:
#Warehouse.rb
has_many :tags, as: :location
has_many :products, through: :tags
#Tag.rb
belongs_to product #
#polymorphic
belongs_to :trackable, polymorphic: true
belongs_to :location, polymorphic: true
Now when I try to get the primary category of that inventory item (belongs_to :product), I keep running into issues; I want to define the category in my iterative inventory list, and have the option to sort/group by it:
#Product.rb
has_one :primary_category_assignment
has_many :rfid_tags, as: :trackable
Each product is assigned to a category - associations are warehouses > tags > products > category_assignment > category. I'm trying to drill down to the level of the last two.
#CategoryAssignment.rb #this is a join table
belongs_to :product, required: true
belongs_to :category, required: true
#Category.rb
has_many :products, through: :category_assignment
Here's some of the accompanying code I'm using to get this set up:
#warehouse_controller.rb
def index
#tags = #warehouse.tags.all.joins(:ancestor_product)
end
#warehouses/index.html.erb
<p><% #tags.each do |tag| %>
tag: <%= tag.number %>,
location_id <%= tag.location_id %>,
<%= tag.product.name %>,
Purchased at $<%= tag.product.purchase_price %></p> #grabs an attribute from the product level
#Next level would reach through the category assignment join table (category_id) to grab the category, or at least order by the category assignment
Schema below for reference:
#schema
create_table "categories", force: :cascade do |t|
t.string "name", null: false
t.text "description"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "position"
end
add_index "categories", ["position"], name: "index_categories_on_position", using: :btree
create_table "category_assignments", force: :cascade do |t|
t.integer "product_id"
t.integer "category_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.boolean "primary", default: false
end
create_table "products", force: :cascade do |t|
t.string "name", null: false
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.float "purchase_price"
t.text "description"
t.datetime "purchase_date"
end
add_index "category_assignments", ["category_id"], name: "index_category_assignments_on_category_id", using: :btree
add_index "category_assignments", ["product_id"], name: "index_category_assignments_on_product_id", using: :btree
create_table "tags", force: :cascade do |t|
t.string "number", null: false
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "location_type"
t.integer "location_id"
t.string "trackable_type"
t.integer "trackable_id"
t.integer "product_id"
end
add_index "tags", ["product_id"], name: "index_rfid_tags_on_ancestor_product_id", using: :btree
add_index "tags", ["location_id"], name: "index_tags_on_location_id", using: :btree
add_index "tags", ["location_type"], name: "index_tags_on_location_type", using: :btree
add_index "tags", ["trackable_id"], name: "index_tags_on_trackable_id", using: :btree
add_index "tags", ["trackable_type"], name: "index_tags_on_trackable_type", using: :btree
add_index "tags", ["user_id"], name: "index_tags_on_user_id", using: :btree
create_table "warehouses", force: :cascade do |t|
t.string "name", null: false
end
Related
I want that if a user has ordered a meal, he can talk to the meal provider... and vice versa...
Users can provide meals and order meals too, like on air bnb you can be a guest or a host (or both)
Exemples:
Lets say we have Bob(buyer) who orders a meal from John(maker) I want that John and Bob can chat together
John(buyer) orders a meal from Mike(maker), John and Mike can chat together.
conversations/index.html.erb
<% #users.each do |user| %>
<%= link_to user.full_name , conversations_path(user_id: user), remote: true, method: :post %>
<% end %>
user.rb (I have doubt in this model...)
has_many :meals #Meals that the user offers
has_many :received_orders, class_name: "Order" #The user receive an order
has_many :placed_orders, through: :meals, class_name: "Order" #The user order a meal
has_many :prepared_orders, through: :received_orders, class_name: "Meal", source: :meal #The user has prepared the order
####maybe this way below....TODO
# has_many :meals
# has_many :orders_as_a_customer, class_name: "Order"# same as: has_many :orders
# has_many :orders_as_a_seller, through: :orders_as_a_customer, class_name: "Meal", source: :meal
# has_many :orders, through: :meals
order.rb
class Order < ApplicationRecord
before_save :calculate_price
belongs_to :user
belongs_to :meal
has_many :notifications, as: :topic
monetize :amount_cents, as: :amount
def payment
self.payment_status = true
self.save
end
def calculate_price
self.amount = (self.quantity * meal.price)
end
end
Well I've followed this tutorial to create my chat, and I bet it's possible to adjust to my app to it...
conversation.rb
class Conversation < ApplicationRecord
has_many :messages, dependent: :destroy
belongs_to :sender, foreign_key: :sender_id, class_name: "User"
belongs_to :recipient, foreign_key: :recipient_id, class_name: "User"
validates :sender_id, uniqueness: { scope: :recipient_id }
scope :between, -> (sender_id, recipient_id) do
where(sender_id: sender_id, recipient_id: recipient_id).or(
where(sender_id: recipient_id, recipient_id: sender_id)
)
end
def self.get(sender_id, recipient_id)
conversation = between(sender_id, recipient_id).first
return conversation if conversation.present?
create(sender_id: sender_id, recipient_id: recipient_id)
end
def opposed_user(user)
user == recipient ? sender : recipient
end
end
conversations_controller.rb
class ConversationsController < ApplicationController
def create
#conversation = Conversation.get(current_user.id, params[:user_id])
add_to_conversations unless conversated?
respond_to do |format|
format.js
end
end
def index
session[:conversations] ||= []
#users = User.all.where.not(id: current_user)
#conversations = Conversation.includes(:recipient, :messages).find(session[:conversations])
end
def close
#conversation = Conversation.find(params[:id])
session[:conversations].delete(#conversation.id)
respond_to do |format|
format.js
end
end
private
def add_to_conversations
session[:conversations] ||= []
session[:conversations] << #conversation.id
end
def conversated?
session[:conversations].include?(#conversation.id)
end
end
my actual schema.rb
ActiveRecord::Schema.define(version: 20170629192651) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
create_table "attachinary_files", force: :cascade do |t|
t.string "attachinariable_type"
t.integer "attachinariable_id"
t.string "scope"
t.string "public_id"
t.string "version"
t.integer "width"
t.integer "height"
t.string "format"
t.string "resource_type"
t.datetime "created_at"
t.datetime "updated_at"
t.index ["attachinariable_type", "attachinariable_id", "scope"], name: "by_scoped_parent", using: :btree
end
create_table "categories", force: :cascade do |t|
t.string "name"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "conversations", force: :cascade do |t|
t.integer "recipient_id"
t.integer "sender_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "order_id"
t.index ["order_id"], name: "index_conversations_on_order_id", using: :btree
t.index ["recipient_id", "sender_id"], name: "index_conversations_on_recipient_id_and_sender_id", unique: true, using: :btree
end
create_table "ingredients", force: :cascade do |t|
t.string "name"
t.integer "meal_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["meal_id"], name: "index_ingredients_on_meal_id", using: :btree
end
create_table "meals", force: :cascade do |t|
t.string "menu_name"
t.integer "portion"
t.date "availability"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "user_id"
t.integer "category_id"
t.string "images"
t.string "location"
t.float "latitude"
t.float "longitude"
t.integer "price"
t.index ["user_id"], name: "index_meals_on_user_id", using: :btree
end
create_table "messages", force: :cascade do |t|
t.text "body"
t.integer "user_id"
t.integer "conversation_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["conversation_id"], name: "index_messages_on_conversation_id", using: :btree
t.index ["user_id"], name: "index_messages_on_user_id", using: :btree
end
create_table "notifications", force: :cascade do |t|
t.boolean "read", default: false
t.string "content"
t.integer "user_id"
t.string "topic_type"
t.integer "topic_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "order_id"
t.index ["order_id"], name: "index_notifications_on_order_id", using: :btree
t.index ["topic_type", "topic_id"], name: "index_notifications_on_topic_type_and_topic_id", using: :btree
t.index ["user_id"], name: "index_notifications_on_user_id", using: :btree
end
create_table "orders", force: :cascade do |t|
t.text "message"
t.boolean "payment_status", default: false
t.integer "quantity"
t.integer "user_id"
t.integer "meal_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "amount_cents", default: 0, null: false
t.json "payment"
t.index ["meal_id"], name: "index_orders_on_meal_id", using: :btree
t.index ["user_id"], name: "index_orders_on_user_id", using: :btree
end
create_table "reviews", force: :cascade do |t|
t.integer "rating"
t.text "comment"
t.integer "meal_id"
t.integer "user_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["meal_id"], name: "index_reviews_on_meal_id", using: :btree
t.index ["user_id"], name: "index_reviews_on_user_id", using: :btree
end
create_table "users", force: :cascade do |t|
t.string "email", default: "", null: false
t.string "encrypted_password", default: "", null: false
t.string "reset_password_token"
t.datetime "reset_password_sent_at"
t.datetime "remember_created_at"
t.integer "sign_in_count", default: 0, null: false
t.datetime "current_sign_in_at"
t.datetime "last_sign_in_at"
t.inet "current_sign_in_ip"
t.inet "last_sign_in_ip"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "provider"
t.string "uid"
t.string "facebook_picture_url"
t.string "first_name"
t.string "last_name"
t.string "token"
t.datetime "token_expiry"
t.string "nickname"
t.string "avatar"
t.index ["email"], name: "index_users_on_email", unique: true, using: :btree
t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true, using: :btree
end
add_foreign_key "conversations", "orders"
add_foreign_key "meals", "users"
add_foreign_key "messages", "conversations"
add_foreign_key "messages", "users"
add_foreign_key "notifications", "orders"
add_foreign_key "notifications", "users"
add_foreign_key "orders", "meals"
add_foreign_key "orders", "users"
add_foreign_key "reviews", "meals"
add_foreign_key "reviews", "users"
end
Concluding from the comments, you'd need to have different models. Here are the ones that make sense to me:
class User < ApplicationRecord
has_many :meals
has_many :orders
has_many :sent_messages, :class => 'ChatMessage', :foreign_key => 'sender_id'
has_many :received_messages, :class => 'ChatMessage', :foreign_key => 'receiver_id'
end
class Meal < ApplicationRecord
belongs_to :user
belongs_to :order_item
end
class Order < ApplicationRecord
belongs_to :user
has_many :order_items
end
class OrderItem < ApplicationRecord
belongs_to :order
has_one :meal
end
class ChatMessage < ApplicationRecord
belongs_to :sender, :class => 'User'
belongs_to :receiver, :class => 'User'
end
To make more simple I do have
class User
has_many :questions, trough: votes
has_many :questions #(as the author)
has_many :votes
end
Forgot to add foreign_key when created, now I don't know how to add it to specific (has_many through) association
schema.rb
enable_extension "plpgsql"
create_table "answers", force: :cascade do |t|
t.text "body"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "question_id"
t.integer "user_id"
t.boolean "best", default: false
end
add_index "answers", ["question_id"], name: "index_answers_on_question_id", using: :btree
add_index "answers", ["user_id"], name: "index_answers_on_user_id", using: :btree
create_table "attachments", force: :cascade do |t|
t.string "file"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "attachable_id"
t.string "attachable_type"
end
add_index "attachments", ["attachable_id", "attachable_type"], name: "index_attachments_on_attachable_id_and_attachable_type", using: :btree
create_table "questions", force: :cascade do |t|
t.string "title"
t.text "body"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "user_id"
end
add_index "questions", ["title"], name: "index_questions_on_title", using: :btree
add_index "questions", ["user_id"], name: "index_questions_on_user_id", using: :btree
create_table "users", force: :cascade do |t|
t.string "name"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "email", default: "", null: false
t.string "encrypted_password", default: "", null: false
t.string "reset_password_token"
t.datetime "reset_password_sent_at"
t.datetime "remember_created_at"
t.integer "sign_in_count", default: 0, null: false
t.datetime "current_sign_in_at"
t.datetime "last_sign_in_at"
t.inet "current_sign_in_ip"
t.inet "last_sign_in_ip"
end
add_index "users", ["email"], name: "index_users_on_email", unique: true, using: :btree
add_index "users", ["name"], name: "index_users_on_name", unique: true, using: :btree
add_index "users", ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true, using: :btree
create_table "votes", force: :cascade do |t|
t.integer "votable_id"
t.string "votable_type"
t.integer "user_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
add_index "votes", ["user_id", "votable_id"], name: "index_votes_on_user_id_and_votable_id", unique: true, using: :btree
add_foreign_key "answers", "questions", on_delete: :cascade
add_foreign_key "questions", "users", on_delete: :cascade
end
Run this command on your console
rails g migration AddForeignKeyToVotes user:references question:references
This will generate a xxxx_add_foreign_key_to_votes.rb file under db/migrate/ with following contents
class AddForeignKeyToVotes < ActiveRecord::Migration
def change
add_reference :votes, :user, index: true, foreign_key: true
add_reference :votes, :question, index: true, foreign_key: true
end
end
Are you really need foreign keys?
Many of Rails developers are comfortable with the way Rails handles relationships in the application rather than the database.
for your case:
class User
has_many :questions, trough: votes
has_many :questions #(as the author)
has_many :votes
end
if votes table has question_id and user_id that is enough to define the relation without any foreign keys, unless you have a reason and really need this foreign keys to be defined database level.
Read THIS SECTION carefully, Rails is using Convention over Configuration.
As a small example: how your User model know which table to query in and retrieve the data, without any configuration it search for table with same name users (convention) and use it, same for foreign keys.
According to your comment you have a model something as Stackoverflow, you have a User who can ask a Question and can answer a Question in this case you may have something like:
class User
has_many :asked_questions, class_name: 'Question' # user can ask many questions
has_many :voted_questions, through: :votes, source: 'question'
has_many :votes # to get all votes this user did
end
class Question
has_many :votes # to get all votes for a question
belongs_to :user
end
class Vote
belongs_to :user
belongs_to :question
end
Database will be something like:
# Table User
# Table Question (user_id)
# Table Vote (user_id, question_id)
Let's say you want to get Questions user asked they it will be:
user = User.first
user.asked_questions
if you want get Questions who user votes for:
user.voted_questions
I've built a rails app and on pushing it up to heroku and running heroku run rake db:migrate i receive the error:
Migrating to CreateFollowingRelationships (20160615113231)
(0.4ms) BEGIN
== 20160615113231 CreateFollowingRelationships: migrating =====================
-- create_table(:following_relationships)
(7.1ms) CREATE TABLE "following_relationships" ("id" serial primary key, "follower_id" integer, "followed_user_id" integer, "created_at" timestamp NOT NULL, "updated_at" timestamp NOT NULL, CONSTRAINT "fk_rails_39102b381e"
FOREIGN KEY ("follower_id")
REFERENCES "followers" ("id")
, CONSTRAINT "fk_rails_048c8f7cd9"
FOREIGN KEY ("followed_user_id")
REFERENCES "followed_users" ("id")
)
(0.5ms) ROLLBACK
(0.5ms) SELECT pg_advisory_unlock(2837140123622957145)
rails aborted!
StandardError: An error has occurred, this and all later migrations canceled:
PG::UndefinedTable: ERROR: relation "followers" does not exist
: CREATE TABLE "following_relationships" ("id" serial primary key, "follower_id" integer, "followed_user_id" integer, "created_at" timestamp NOT NULL, "updated_at" timestamp NOT NULL, CONSTRAINT "fk_rails_39102b381e"
FOREIGN KEY ("follower_id")
REFERENCES "followers" ("id")
, CONSTRAINT "fk_rails_048c8f7cd9"
FOREIGN KEY ("followed_user_id")
REFERENCES "followed_users" ("id")
)
The relationship I have setup is for users to follow users and be followed. It works perfectly in development. This is the first time i've had this error and can't find a solution. Please see the rest of my code below.
db/schema.rb
ActiveRecord::Schema.define(version: 20160618122126) do
create_table "chats", force: :cascade do |t|
t.integer "user_id"
t.string "title"
t.text "description"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "profile_id"
t.index ["profile_id"], name: "index_chats_on_profile_id"
t.index ["user_id"], name: "index_chats_on_user_id"
end
create_table "comments", force: :cascade do |t|
t.integer "profile_id"
t.integer "chat_id"
t.text "body"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["chat_id"], name: "index_comments_on_chat_id"
t.index ["profile_id"], name: "index_comments_on_profile_id"
end
create_table "following_relationships", force: :cascade do |t|
t.integer "follower_id"
t.integer "followed_user_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["followed_user_id"], name: "index_following_relationships_on_followed_user_id"
t.index ["follower_id"], name: "index_following_relationships_on_follower_id"
end
create_table "locations", force: :cascade do |t|
t.string "locationable_type"
t.integer "locationable_id"
t.string "suburb"
t.integer "user_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "address"
t.string "state"
t.string "country"
t.string "postcode"
t.float "latitude"
t.float "longitude"
t.index ["locationable_type", "locationable_id"], name: "index_locations_on_locationable_type_and_locationable_id"
t.index ["user_id"], name: "index_locations_on_user_id"
end
create_table "orders", force: :cascade do |t|
t.integer "buyer_id"
t.integer "seller_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "posts", force: :cascade do |t|
t.integer "profile_id"
t.integer "user_id"
t.string "title"
t.text "body"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["profile_id"], name: "index_posts_on_profile_id"
t.index ["user_id"], name: "index_posts_on_user_id"
end
create_table "profiles", force: :cascade do |t|
t.integer "user_id"
t.text "bio"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["user_id"], name: "index_profiles_on_user_id"
end
create_table "tutoring_relationships", force: :cascade do |t|
t.integer "tutor_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "tutee_id"
t.index ["tutee_id"], name: "index_tutoring_relationships_on_tutee_id"
t.index ["tutor_id"], name: "index_tutoring_relationships_on_tutor_id"
end
create_table "users", force: :cascade do |t|
t.string "email", null: false
t.string "password_digest", null: false
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "username"
t.boolean "tutor", default: false
t.index ["email"], name: "index_users_on_email", unique: true
t.index ["username"], name: "index_users_on_username", unique: true
end
create_table "votes", force: :cascade do |t|
t.string "votable_type"
t.integer "votable_id"
t.string "voter_type"
t.integer "voter_id"
t.boolean "vote_flag"
t.string "vote_scope"
t.integer "vote_weight"
t.datetime "created_at"
t.datetime "updated_at"
t.index ["votable_id", "votable_type", "vote_scope"], name: "index_votes_on_votable_id_and_votable_type_and_vote_scope"
t.index ["voter_id", "voter_type", "vote_scope"], name: "index_votes_on_voter_id_and_voter_type_and_vote_scope"
end
end
models/following_relationship.rb
class FollowingRelationship < ApplicationRecord
belongs_to :follower, class_name: 'User'
belongs_to :followed_user, class_name: 'User'
end
models/user.rb
class User < ActiveRecord::Base
has_one :profile, dependent: :destroy
has_many :chats
validates :email, presence: true, uniqueness: true
validates :password_digest, presence: true
has_many :follower_relationships,
foreign_key: :followed_user_id,
class_name: 'FollowingRelationship'
has_many :followers, through: :follower_relationships
has_many :followed_user_relationships,
foreign_key: :follower_id,
class_name: "FollowingRelationship"
has_many :followed_users, through: :followed_user_relationships
has_many :tutee_relationships,
foreign_key: :tutor_id,
class_name: 'TutoringRelationship'
has_many :tutees, through: :tutee_relationships
has_many :tutor_relationships,
foreign_key: :tutee_id,
class_name: 'TutoringRelationship'
has_many :tutors, through: :tutor_relationships
def following? user
followed_user_ids.include?(user.id)
end
def is_connected? user
tutee_ids.include?(user.id)
end
end
Please excuse the messy model, it would usually be in a helper method but for this post it's here. If anyone has any ideas please let me know! Thanks
I have Users and Albums tables. The foreign key for the Albums table is the user_id.
My Active Record query is:
def show
#album = Album.find(params[:id])
#added_by = User.joins('LEFT OUTER JOIN albums ON albums.id = (params[:id])')
end
In my ERB I have:
<%= added_by.name %>
My schema is:
ActiveRecord::Schema.define(version: 20150930203820) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
create_table "albums", force: :cascade do |t|
t.string "artist", null: false
t.integer "year"
t.string "title", null: false
t.string "pressing"
t.string "format"
t.string "label"
t.string "genre"
t.text "image_url"
t.string "tracklist"
t.string "country"
t.text "comment"
t.boolean "favorite"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "user_id"
end
add_index "albums", ["user_id"], name: "index_albums_on_user_id", using: :btree
create_table "users", force: :cascade do |t|
t.string "email", null: false
t.string "pic_url"
t.string "name", null: false
t.string "favorite"
t.string "crypted_password"
t.string "salt"
t.datetime "created_at"
t.datetime "updated_at"
t.datetime "last_login_at"
t.datetime "last_logout_at"
t.datetime "last_activity_at"
t.string "last_login_from_ip_address"
end
add_index "users", ["last_logout_at", "last_activity_at"], name: "index_users_on_last_logout_at_and_last_activity_at", using: :btree
add_index "users", ["name", "email"], name: "index_users_on_name_and_email", unique: true, using: :btree
add_foreign_key "albums", "users"
end
Simply Try:
#album.user.name
If this now work then Make sure you have set Active Record Associations in models like:
# user.rb
class User < ActiveRecord::Base
has_many :albums
end
# album.rb
class Album < ActiveRecord::Base
belongs_to :user
end
I am writing a Rails 4.2 app with models user, notecard, tag and tagging (for the m-2-m relationship).
A tag can have multiple notecards and a notecard can have multiple tags.
A card belongs to a user and a tag DOESN'T belong to a user.
How can I scope the tags that only a user has used?
I want to have an index of all tags and an index of the tags a user has actually used.
Thanks!
Here is the schema, as I don't have an idea on how to implement the where clause to index the tags a user has used.
to give you an idea, I'm looking for something like this
def index_of_used_tags
#Take all tags, return those that have cards from this user
end
class User < ActiveRecord::Base
has_many :comments
has_many :folders
has_many :cards
end
class Tag < ActiveRecord::Base
has_many :taggings
has_many :cards, through: :taggings
validates_presence_of :name
validates_uniqueness_of :name
end
class Folder < ActiveRecord::Base
belongs_to :user
validates_presence_of :name
validates_uniqueness_of :name, scope: :user_id
end
class Card < ActiveRecord::Base
belongs_to :user
belongs_to :folder
has_many :taggings
has_many :tags, through: :taggins
end
ActiveRecord::Schema.define(version: 20150604113358) do
enable_extension "plpgsql"
create_table "cards", force: :cascade do |t|
t.string "object"
t.text "content"
t.string "source"
t.integer "user_id"
t.integer "folder_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
add_index "cards", ["folder_id"], name: "index_cards_on_folder_id", using: :btree
add_index "cards", ["user_id"], name: "index_cards_on_user_id", using: :btree
create_table "comments", force: :cascade do |t|
t.text "content"
t.string "commentable_type"
t.integer "commentable_id"
t.integer "user_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
add_index "comments", ["user_id"], name: "index_comments_on_user_id", using: :btree
create_table "folders", force: :cascade do |t|
t.string "name"
t.integer "user_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
add_index "folders", ["user_id"], name: "index_folders_on_user_id", using: :btree
create_table "taggings", force: :cascade do |t|
t.integer "card_id"
t.integer "tag_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
add_index "taggings", ["card_id"], name: "index_taggings_on_card_id", using: :btree
add_index "taggings", ["tag_id"], name: "index_taggings_on_tag_id", using: :btree
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 "users", force: :cascade do |t|
t.string "fname"
t.string "lname"
t.boolean "admin", default: false
t.string "email", default: "", null: false
t.string "encrypted_password", default: "", null: false
t.string "reset_password_token"
t.datetime "reset_password_sent_at"
t.datetime "remember_created_at"
t.integer "sign_in_count", default: 0, null: false
t.datetime "current_sign_in_at"
t.datetime "last_sign_in_at"
t.inet "current_sign_in_ip"
t.inet "last_sign_in_ip"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
add_index "users", ["email"], name: "index_users_on_email", unique: true, using: :btree
add_index "users", ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true, using: :btree
add_foreign_key "cards", "folders"
add_foreign_key "cards", "users"
add_foreign_key "comments", "users"
add_foreign_key "folders", "users"
add_foreign_key "taggings", "cards"
add_foreign_key "taggings", "tags" end
You can set up a has_many through relationship between User and Tag
class User < ActiveRecord::Base
has_many :comments
has_many :folders
has_many :cards
has_many :tags, through: :cards
end
Then user.tags would give you all the tags the user has used.
User.includes(:cards => :taggings).where('users.id = ?', current_user.id)
Try this query