about user authentication with username and subdomain - subdomain

I am using devise as my authentication system. And i want to
authenticate user with username along with subdomain.
It seems that devise needs both the username and subdomain field in
the same table which is not in my case.
I have subdomain field in Company table while username and password in
the UserAccount table.
And there is references_many relation between UserAccount and Company table
Now how can i authenticate the user with both username and subdomain
Please help me out.

!#user.rb
devise :all, :authentication_keys => [:email, :subdomain]
OR
!#config/initializer/devise.rb
Devise.setup do |config|
config.authentication_keys = [ :email, :subdomain ]
end
!#login.erb.html
...
f.hidden_field :subdomain, :value => current_subdomain
...
!#user.rb
def self.find_for_authentication(conditions={})
find(:first, :conditions => { :companies => { :subdomain => conditions.delete(:subdomain) } }, :joins => :companies)
end

Related

Rails connect to remote db

How to properly connect to remote db?
Now i have
def db_params
{:adapter => "mysql2",
:host => "host",
:username => "name",
:password => "pass",
:database => "mydb"}
end
def connect_to_remote_db
ActiveRecord::Base.establish_connection(db_params)
end
When i write connect_to_remote_db it seems ok
I know that remote db has table 'Team'
but when i write Team
in console it returns me uninitialized constant Team
How to handle it properly?
When you call Team ActiveRecord's primary connection is looked up, hence the error.
You could probably wrap that in class.
Since I had dealt with similar situation, you could have that connection in database.ymlitself and use.
development:
adapter: mysql2
other stuff...
db_2:
adapter: mysql2
other stuff..
Then create a class
class Team < ActiveRecord::Base
establish_connection(:db_2)
self.table_name = "teams"
end
from - https://stackoverflow.com/a/26574386/2231236
You need to create model in your application ( of that remote db table) and establish connection. Example:
team.rb
class Team< ActiveRecord::Base
establish_connection "remote_db"
end
If you have multiple table you want to use from that remote db, you can make module and just include it in every model for remote db table.
Module example:
module RemoteConnection
extend ActiveSupport::Concern
included do
establish_connection "remote_db"
end
end
and than
class Team< ActiveRecord::Base
include RemoteConnection
end
Use database.yml file to store connections:
...
remote_db:
:adapter => "mysql2",
:host => "host",
:username => "name",
:password => "pass",
:database => "mydb"
...

How to establish connection from a rake task?

I need to create a rake task that gets the table rows from a MySQL database, parse the data, and insert into an Oracle database. The databases are on two different hosts.
My current attempt:
namespace :import_from_mysql do
class MySQLConnection < ActiveRecord::Base
self.abstract_class = true
establish_connection({
:adapter => 'mysql',
:host => 'xxx.xxx.com',
:database => 'sample_database',
:username => 'username',
:password => 'password'
})
end
class MySQLTable < MySQLConnection
self.table_name = "users"
self.primary_key = "id"
self.inheritance_column = "something_unique_here"
end
desc "Parse data before inserting to oracle database"
task :insert_to_oracle => :environment do |t|
puts "Rake task has begun...\n\n"
puts "Parsing data from MYSQL...\n\n"
MySQLTable.establish_connection
puts "Rake task has completed!"
end
end
But the MySQLTable.establish_connection establishes a connection to my local database which is sqlite even though I'm trying to connect to a mysql_adapter.
When I tried to establish a connection using the command below, I was able to connect to a MySQL adapter but I don't know how I can access my tables after the connection was established:
ActiveRecord::Base.establish_connection({:adapter => "mysql", :database => "sample_database", :host => "xxx.xxx.com", :username => "username", :password => "password" })
Any idea on why it keeps on connecting to sqlite? And after successfully establishing a connection to mysql, how do I select table rows after the MySQLTable.establish_connection statement?
With the connection generated using ActiveRecord::Base you can execute SQL statements against whatever database you connect to. Like so:
connection = ActiveRecord::Base.establish_connection(
:adapter => "mysql",
:host => "faraway",
:username => "myuser",
:password => "mypass",
:database => "somedatabase"
)
connection.execute('SELECT * FROM users')
Once established, the connection can also be referenced from ActiveRecord::Base class.
ActiveRecord::Base.establish_connection(...)
ActiveRecord::Base.connection.execute(...)
You can use mysql2 gem (https://github.com/brianmario/mysql2) inside your rake task.
client = Mysql2::Client.new(:host => "localhost", :username => "username", :database => "sample_database", :password => "password")
users = client.query("SELECT * FROM users")
Thought it might be helpful for someone else. The following worked for me!
connection = ActiveRecord::Base.establish_connection(
:adapter => "mysql",
:host => "faraway",
:username => "myuser",
:password => "mypass",
:database => "somedatabase"
)
#connection = ActiveRecord::Base.connection
result = #connection.exec_query('SELECT * FROM users')
result.each do |row|
puts row
end
Here, users is an already existing table in the "somedatabase".
although I am a noob with connections and "database back office" my trivial approach works like a charm, and there is no need with parameters in rake task that is for updating "domain tables" that contain only defining data like legal or help texts:
pre_db = ActiveRecord::Base.establish_connection('preproduction').connection
prod_db = ActiveRecord::Base.establish_connection('online').connection
and in database.yml I defined the databases. ("preproduction" is a step between dev and prod in my case and a real environment like "development". where 'online' is almost the same as 'production' (I made a different entry only for security reasons - not to destroy production if database.yml gets uploaded)

Dynamic second database Ruby

I want to add a second read-only database to my application based on a variable aside the SQLite file I'm developing with.
So, there should be three databases.
1. Local SQLite file
2. Production Read-only MySQL database
3. Test Read-only MySQL database
This test database has new columns added and will be pushed as production database soon.
From this SO-Q, I do not understand what the solution is.
I already use establish_connection.
establish_connection(
:adapter => 'mysql2',
:database => "db1",
:username => "username",
:password => "p*ssw*rd",
:host => "ho.st.com"
)
This db1 is the production db without the extra table columns.
db2 is the test db with the extra table columns.
establish_connection(
:adapter => 'mysql2',
:database => "db2",
:username => "username",
:password => "p*ssw*rd",
:host => "ho.st.com"
)
I thought this could be a solution:
In the models of the tables from the MySQL databases:
config = 'test'
case config
when 'test'
establish_connection(
:adapter => 'mysql2',
:database => "db1",
:username => "username",
:password => "p*ssw*rd",
:host => "ho.st.com"
)
else
establish_connection(
:adapter => 'mysql2',
:database => "db2",
:username => "username",
:password => "p*ssw*rd",
:host => "ho.st.com"
)
end
But now I have to edit all 'affected' models when I change the status. Is there a way to variabilise (is that even a word?) this so I only have to edit this config once?
I've tried via Application_controller.rb, but this didn't work.
# Application_controller.rb
def get_config_status
return 'test'
end
# model.rb
config = get_config_status() #=> undefined method `get_config_status' for Regio(Table doesn't exist):Class
# or
config = Application.get_config_status #=> uninitialized constant Regio::Application
Or should I consider totally something else?
To be honest, I don't like putting usernames and passwords in Models. Is this a possible thread for hackers?
Summary
What I'm trying to accomplish is:
Set one variable so my application uses db2 instead of db1.
The octopus gem might be helpful.
https://github.com/tchandy/octopus
You can select the database at query level,
User.where(name: 'Sam').using(:db2)
Or you can select the database per controller action,
class ApplicationController < ActionController::Base
around_filter :select_shard
def select_shard(&block)
Octopus.using(:db1, &block)
end
end
Check out the readme on Github for more examples.

Open connection to mysql DB in the rake task

I have a Rails 3.2 app which use PostgreSQL to store all the information.
But in one Rake task I need to make a connection with the MySQL server. I tried to do this:
ActiveRecord::Base.establish_connection(
:adapter => "mysql2",
:database => "foo",
:user => "root",
:password => "",
)
But it just replace my default PostgreSQL connection with this temporary MySQL.
How to make the additional connection for the instance?
I found a very simple solution: to the the vanila mysql2 gem (https://github.com/brianmario/mysql2)
Now my code looks like:
client = Mysql2::Client.new(:host => "localhost", :username => "root", :database => "foobar", :password => "")
users = client.query("SELECT * FROM users")
After that I have an array of results.
Don't establish it on ActiveRecord::Base.
establish_connection connects to a database from a class, as you've discovered, so when you do it on AR:Base, every subclass of that (to whit, the entire database) has the connection established on it, replacing the current one.
Basically, you create a class for each of the tables you want to connect to, and call the establish connection method in those. If you want to do it in several tables, then create a module with it in and include it.
class MyCustomClass < ActiveRecord::Base
establish_connection(
:adapter => "mysql2",
:database => "foo",
:user => "root",
:password => "",
)
end
MyCustomClass.find(1)

mysql keeps pulling select email NULL for session in RoR

I tried using Devise but since that didn't work out for me, I decided to build the authentication and sessions from scratch. I realize the problem wasn't devise, but it's mysql. For some reason, when I register a user, the information and attributes are stored in the database. When I login using the email and password, it keeps telling me that it's an invalid email/password. The log looks like this:
Processing by SessionsController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"NFudGruZS79uwDrKzbHDQrBjlcwQ7AkC958vI4aHDAs=", "session"=>{"email"=>"first#abc.com", "password"=>"[FILTERED]"}, "commit"=>"Sign in"}
User Load (0.4ms) SELECT `users`.* FROM `users` WHERE `users`.`email` IS NULL LIMIT 1
After some investigation, I know it's not because I didn't install mysql or other gems properly because a brand new app works just fine.
Does anyone know why it's not pulling the email I entered and pulling email is NULL instead?
Should I just create a new database and switch my database.yml file to the new database instead?
Thanks in advance.
EDIT - SOME MORE CODE
user model:
class User < ActiveRecord::Base
attr_accessor :password
attr_accessible :name, :email, :secondary_email, :password, :password_confirmation, :gender
has_many :user_owner_relationships
has_many :owners, :through => :user_owner_relationships
has_many :cash_endowments
has_many :checks, :through => :cash_endowments
has_many :owners, :through => :cash_endowments
email_regex = /\A[\w+\-.]+#[a-z\d\-.]+\.[a-z]+\z/i
validates :email, :presence => true,
:uniqueness => { :case_sensitive => false },
:format => { :with => email_regex }
validates :name, :presence => true,
:length => { :maximum => 40 }
validates :password, :presence => true,
:confirmation => true,
:length => { :within => 6..20 }
sessions_controller (user controller is standard)
def new
#title = "Sign in"
end
def create
user = User.authenticate(params[:email], params[:password])
if user
session[:user_id] = user.id
redirect_to root_path, :notice => "Welcome '#{user.first_name}"
else
flash.now.alert = "Invalid email or password."
render "new"
end
end
Rookie mistake -
It's actually because my new.html.erb for the sessions controller was not pulling the :session symbol from this code:
<%= form_for (:session, :url => sessions_path) do |f| %>
So I just ended up using form_tag instead.