join two tables to get data rails 4 - ruby-on-rails

class Guardian < ActiveRecord::Base
has_many :patients
has_one :user, as: :profile
accepts_nested_attributes_for :user
end
class User < ActiveRecord::Base
belongs_to :profile, :polymorphic => true
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
end
User migration
class DeviseCreateUsers < ActiveRecord::Migration
def change
create_table(:users) do |t|
## Database authenticatable
t.string :email, :null => false, :default => ""
t.string :encrypted_password, :null => false, :default => ""
t.string :username, :null => false
t.string :address
t.integer :age
t.string :gender
t.string :name
t.integer :profile_id
t.string :profile_type
## Recoverable
t.string :reset_password_token
t.datetime :reset_password_sent_at
## Rememberable
t.datetime :remember_created_at
## Trackable
t.integer :sign_in_count, :default => 0, :null => false
t.datetime :current_sign_in_at
t.datetime :last_sign_in_at
t.string :current_sign_in_ip
t.string :last_sign_in_ip
t.timestamps
end
add_index :users, :email, :unique => true
add_index :users, :reset_password_token, :unique => true
end
end
class DeviseCreateUsers < ActiveRecord::Migration
def change
create_table(:users) do |t|
## Database authenticatable
t.string :email, :null => false, :default => ""
t.string :encrypted_password, :null => false, :default => ""
t.string :username, :null => false
t.string :address
t.integer :age
t.string :gender
t.string :name
t.integer :profile_id
t.string :profile_type
## Recoverable
t.string :reset_password_token
t.datetime :reset_password_sent_at
## Rememberable
t.datetime :remember_created_at
## Trackable
t.integer :sign_in_count, :default => 0, :null => false
t.datetime :current_sign_in_at
t.datetime :last_sign_in_at
t.string :current_sign_in_ip
t.string :last_sign_in_ip
t.timestamps
end
add_index :users, :email, :unique => true
add_index :users, :reset_password_token, :unique => true
end
end
Guardian migration
class CreateGuardians < ActiveRecord::Migration
def change
create_table :guardians do |t|
t.string :family_name
t.timestamps
end
end
end
I want to get data from user table and guardian table in a single variable
guardian has one user and user belongs_to guardian as profile(polymorphic). i want to get data from user table and from guardian table where guardian_id=users.profile_id

Try
Guardian.select("*").joins(:user)
Edit:
if you have columns with the same name from the join you can do
Guardian.select("guardians.family_name, guardians.id as g_id, users.id as u_id,
users.name, users.email, users.username, users.address, users.age,
users.gender").joins(:user).where(:users => {:u_id => #user_session.id})

For some reason above answer didn't work for me, so I tried direct sql query
sqlQuery = "select tableA.column1, tableB.column2 from tableA inner join tableB on tableA.some_id = tableB.id"
ActiveRecord::Base.connection.execute(sqlQuery)

Related

Umpermitted parameter in rails devise, even though params .permit(ted)

I have rails (6.0.2.2) project with devise (4.7.1), with two types of accounts: the teachers and the students. The student can to sign up successfully, but there is problem with the teacher for some reason. When I try to make a test account, I get
Unpermitted parameter: :email
error message and my info is not saved in the database.
Migration:
class DeviseCreateTeachers < ActiveRecord::Migration[6.0]
def change
create_table :teachers do |t|
## Database authenticatable
t.string :email, null: false, default: ""
t.string :encrypted_password, null: false, default: ""
## Recoverable
t.string :reset_password_token
t.datetime :reset_password_sent_at
## Rememberable
t.datetime :remember_created_at
t.string :username
t.string :name
t.string :neighborhood
t.integer :pet_skin
t.integer :pet_eyes
t.integer :pet_face
t.integer :pet_accessories
## Trackable
# t.integer :sign_in_count, default: 0, null: false
t.datetime :current_sign_in_at
t.datetime :last_sign_in_at
t.string :current_sign_in_ip
t.string :last_sign_in_ip
## Confirmable
t.string :confirmation_token
t.datetime :confirmed_at
t.datetime :confirmation_sent_at
# t.string :unconfirmed_email # Only if using reconfirmable
## Lockable
t.integer :failed_attempts, default: 0, null: false # Only if lock strategy is :failed_attempts
t.string :unlock_token # Only if unlock strategy is :email or :both
t.datetime :locked_at
t.timestamps null: false
end
add_index :teachers, :email, unique: true
add_index :teachers, :reset_password_token, unique: true
# add_index :teachers, :confirmation_token, unique: true
# add_index :teachers, :unlock_token, unique: true
end
end
my teacher_controller.rb:
class TeacherController < ApplicationController
private
def sign_up_params
params.require(:teacher).permit(:email, :username, :name, :password, :password_confirmation, :neighborhood, :pet_skin, :pet_eyes, :pet_face)
end
def account_update_params
params.require(:teacher).permit(:username, :password, :password_confirmation, :current_password)
end
end
I'm using the default generated teachers/registration/new.html.erb so I think its no problem here.
I DID add a line to config/initializers/devise.rb:
config.authentication_keys = [:username]
to change default log in from email to username, but I don't think this is issue because again students can create the account.
Thanks for your help!
#Tijana I don't know if you have already checked this.
link. If not, it might help
https://github.com/heartcombo/devise#strong-parameters

NoMethodError: undefined method `user' for has_many :through Association

I've attempted to create a has_many :through Association in my rails application, however I get an error when I do the following in the rails console.
2.0.0-p481 :001 > #group = Group.first
Group Load (0.2ms) SELECT "groups".* FROM "groups" ORDER BY "groups"."id" ASC LIMIT 1
=> #<Group id: 1, name: "First Group", description: "Woo", created_at: "2015-02-06 22:19:47", updated_at: "2015-02-06 22:19:47">
2.0.0-p481 :002 > #group.user
NoMethodError: undefined method `user' for #<Group:0x00000004d53eb0>
from /home/jon/.rvm/gems/ruby-2.0.0-p481/gems/activemodel-4.0.2/lib/active_model/attribute_methods.rb:439:in `method_missing'
from /home/jon/.rvm/gems/ruby-2.0.0-p481/gems/activerecord-4.0.2/lib/active_record/attribute_methods.rb:155:in `method_missing'
from (irb):2
from /home/jon/.rvm/gems/ruby-2.0.0-p481/gems/railties-4.0.2/lib/rails/commands/console.rb:90:in `start'
from /home/jon/.rvm/gems/ruby-2.0.0-p481/gems/railties-4.0.2/lib/rails/commands/console.rb:9:in `start'
from /home/jon/.rvm/gems/ruby-2.0.0-p481/gems/railties-4.0.2/lib/rails/commands.rb:62:in `<top (required)>'
from bin/rails:4:in `require'
from bin/rails:4:in `<main>'
My Models:
User:
class User < ActiveRecord::Base
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
before_create :do_mailchimp
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
has_many :memberships
has_many :groups, through: :memberships
def do_mailchimp
gb = Gibbon::API.new("API")
gb.lists.subscribe({:id => 'ID',
:email => {:email => self.email },:double_optin => false})
end
end
Group:
class Group < ActiveRecord::Base
has_many :memberships
has_many :users, through: :memberships
end
Membership:
class Membership < ActiveRecord::Base
belongs_to :user
belongs_to :group
end
My Migrations:
DeviseCreateUsers:
class DeviseCreateUsers < ActiveRecord::Migration
def change
create_table(:users) do |t|
## Database authenticatable
t.string :email, null: false, default: ""
t.string :encrypted_password, null: false, default: ""
## Recoverable
t.string :reset_password_token
t.datetime :reset_password_sent_at
## Rememberable
t.datetime :remember_created_at
## Trackable
t.integer :sign_in_count, default: 0, null: false
t.datetime :current_sign_in_at
t.datetime :last_sign_in_at
t.string :current_sign_in_ip
t.string :last_sign_in_ip
## Confirmable
# t.string :confirmation_token
# t.datetime :confirmed_at
# t.datetime :confirmation_sent_at
# t.string :unconfirmed_email # Only if using reconfirmable
## Lockable
# t.integer :failed_attempts, default: 0, null: false # Only if lock strategy is :failed_attempts
# t.string :unlock_token # Only if unlock strategy is :email or :both
# t.datetime :locked_at
t.timestamps
end
add_index :users, :email, unique: true
add_index :users, :reset_password_token, unique: true
# add_index :users, :confirmation_token, unique: true
# add_index :users, :unlock_token, unique: true
end
end
CreateGroups:
class CreateGroups < ActiveRecord::Migration
def change
create_table :groups do |t|
t.string :name
t.string :description
t.timestamps
end
end
end
CreateMemberships:
class CreateMemberships < ActiveRecord::Migration
def change
create_table :memberships do |t|
t.timestamps
end
end
end
AddUserAndGroupIdToMemberships:
class AddUserAndGroupIdToMemberships < ActiveRecord::Migration
def change
add_column :memberships, :user_id, :integer
add_index :memberships, :user_id
add_column :memberships, :group_id, :integer
add_index :memberships, :group_id
end
end
My Schema:
ActiveRecord::Schema.define(version: 20150206225251) do
create_table "groups", force: true do |t|
t.string "name"
t.string "description"
t.datetime "created_at"
t.datetime "updated_at"
end
create_table "memberships", force: true do |t|
t.datetime "created_at"
t.datetime "updated_at"
t.integer "user_id"
t.integer "group_id"
end
add_index "memberships", ["group_id"], name: "index_memberships_on_group_id"
add_index "memberships", ["user_id"], name: "index_memberships_on_user_id"
create_table "users", force: true 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.string "current_sign_in_ip"
t.string "last_sign_in_ip"
t.datetime "created_at"
t.datetime "updated_at"
end
add_index "users", ["email"], name: "index_users_on_email", unique: true
add_index "users", ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true
end
Thank you for your time hope you can help.
You defined that a Group has_many :users. Therefore a group does not have an user method, but an users method:
#group = Group.first
#group.users #=> returns an array with all users in the first group
#group.users.first #=> returns the first user in the first group

Migration could not be done undefined method `apply_schema=` for devise

I am getting this error while running rake db:migrate
rake db:migrate
rake aborted!
undefined method `apply_schema=' for Devise:Module
/home/dexter/Desktop/Triton/config/initializers/devise.rb:14:in `block in <top (required)>'
I have checked devise.rb
# Automatically apply schema changes in tableless databases
config.apply_schema = false
devise users model
class DeviseCreateUsers < ActiveRecord::Migration
def change
create_table(:users) do |t|
## Database authenticatable
t.string :email, :null => false, :default => ""
t.string :encrypted_password, :null => false, :default => ""
## Recoverable
t.string :reset_password_token
t.datetime :reset_password_sent_at
## Rememberable
t.datetime :remember_created_at
## Trackable
t.integer :sign_in_count, :default => 0
t.datetime :current_sign_in_at
t.datetime :last_sign_in_at
t.string :current_sign_in_ip
t.string :last_sign_in_ip
## Encryptable
# t.string :password_salt
## Confirmable
# t.string :confirmation_token
# t.datetime :confirmed_at
# t.datetime :confirmation_sent_at
# t.string :unconfirmed_email # Only if using reconfirmable
## Lockable
t.integer :failed_attempts, :default => 0 # Only if lock strategy is :failed_attempts
t.string :unlock_token # Only if unlock strategy is :email or :both
t.datetime :locked_at
## Token authenticatable
# t.string :authentication_token
t.string :user_name
t.string :first_name
t.string :last_name
t.string :user_type
t.string :about
t.timestamps
end
add_index :users, :email, :unique => true
add_index :users, :reset_password_token, :unique => true
# add_index :users, :confirmation_token, :unique => true
add_index :users, :unlock_token, :unique => true
# add_index :users, :authentication_token, :unique => true
end
end

One to Many Relationship: List of many not showing up

I have a simple one to many relationship mapping users to posts. Here is the relevant part of the schema:
create_table "users", :force => true do |t|
t.string "username"
t.string "first_name"
t.string "last_name"
t.string "email"
t.string "password"
t.string "status", :default => "User"
t.string "img_url"
t.text "bio"
t.integer "num_posts", :default => 0
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
create_table "posts", :force => true do |t|
t.string "subject"
t.text "body"
t.integer "user_id"
t.integer "section_id"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
And here are the models:
class User < ActiveRecord::Base
attr_accessible :bio, :email, :first_name, :img_url, :last_name, :num_posts, :password, :status, :username
has_many :posts
has_many :comments
end
class Post < ActiveRecord::Base
attr_accessible :body, :section_id, :subject, :tag_ids, :user_id
belongs_to :user
belongs_to :section
has_and_belongs_to_many :tags
has_many :comments
end
I go into the rails console and create a new user doing User.create(attributes) and a new post doing Post.create(some attributes), assinging them to p1 and u1, respectively, then I do p1.user = u1.
Now when I do p1.user, I get a u1 object. Moreover, I can see that the user_id key is set to the key of u1 in the DB. However, when I do u1.posts, I get an empty list. How can I get a list of all of the posts that belong to a given user?
Ideally, when creating posts, you can create like this:
user.posts.create!({attributes})
Here in your case it could be the problem with association caching. Try
u1.reload.posts

Creating Associations in Rails using has_many and belongs_to

I know there are a lot of topics on this already but I couldn't find any that were what I'm trying to do. I'm just learning Rails and although I know this is probably a pretty simple fix, I'm stumped.
I'm creating a "Timeline" site. I have user accounts set up, and the user can create timelines. But, what I need to do is associate multiple timeline "events" (items to go in the timeline, the model for these is called Event) with each timeline (the model for which is called Timeline_Object). More plainly - a user has multiple timelines, and a timeline has multiple events.
The problem is that I can't get events set up with the timeline correctly. I think the association is set up correctly between users and timelines, but I'm not completely sure how to figure out what's wrong. Here are my models:
class User < ActiveRecord::Base
has_many :timeline_objects
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
# Setup accessible (or protected) attributes for your model
attr_accessible :email, :password, :password_confirmation,
:remember_me, :user_name
end
class TimelineObject < ActiveRecord::Base
belongs_to :user
attr_accessible :title, :user_id
has_many :events
end
class Event < ActiveRecord::Base
belongs_to :timeline_object
attr_accessible :date, :description, :time, :title, :image,
:image_width, :image_height, :timeline_objects
has_attached_file :image, :styles => { :large => "500x500>", :medium => "400x400#", :thumb => "100x100>" }
after_post_process :save_image_dimensions
validates :title, presence: true
validates :image, presence: true
validates :time, presence: true
validates :date, presence: true
def save_image_dimensions
geo = Paperclip::Geometry.from_file(image.queued_for_write[:original])
self.image_width = geo.width
self.image_height = geo.height
end
end
After running some migrations to set up the keys in the database, this is what my schema looks like:
ActiveRecord::Schema.define(:version => 20130402144923) do
create_table "events", :force => true do |t|
t.string "title"
t.string "description"
t.string "date"
t.string "time"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.string "image_file_name"
t.string "image_content_type"
t.integer "image_file_size"
t.datetime "image_updated_at"
t.integer "image_height"
t.integer "image_width"
t.integer "timeline_objects"
end
add_index "events", ["timeline_objects"], :name => "index_events_on_timeline_objects"
create_table "timeline_objects", :force => true do |t|
t.string "title"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.integer "user_id"
end
add_index "timeline_objects", ["user_id"], :name => "index_timeline_objects_on_user_id"
create_table "users", :force => true do |t|
t.string "user_name"
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
t.datetime "current_sign_in_at"
t.datetime "last_sign_in_at"
t.string "current_sign_in_ip"
t.string "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
add_index "users", ["reset_password_token"], :name => "index_users_on_reset_password_token", :unique => true
end
When I go to show the timeline (at which point all the events should be displayed), I try to loop through them with
<% #timeline_object.events.each do |event| %>
That line of code produces this error:
SQLite3::SQLException: no such column: events.timeline_object_id: SELECT "events".* FROM "events" WHERE "events"."timeline_object_id" = 4
So I realize that means I'm missing something in my database, but I'm not sure what I should change/add to make it all work.
Let me know if you need any additional info/code. Thanks in advance.
In your Events schema, you have:
t.integer "timeline_objects"
but, it should be:
t.integer "timeline_object_id"
Run a new migration to fix it:
rename_column :events, :timeline_objects, :timeline_object_id
Since each event belongs to a TimelineObject, then it needs a column that identifies the id of the object that it's associated to.

Resources