在Rails控制器操作中创建Mysql用户

时间:2013-06-20 09:28:58

标签: mysql ruby-on-rails ruby ruby-on-rails-3 ruby-on-rails-3.2

使用管理员仅用于创建另一个应用的多个实例的应用。

换句话说,app A将用于在服务器上创建app B克隆,并创建在子域new_clone.domain.com上运行该克隆应用所需的所有配置。

管理克隆应用程序,也创建了apache配置文件,unicorn server settings文件。管理运行rake db:create; db:migrate但我使用mysql的root用户执行此操作。

在我克隆应用时,我为新克隆的应用生成database.yml个文件,此时usernamepassword设置为root,但我想为每个克隆的应用程序设置不同的用户。

应用A有一个名为Subdomain的模型,在subdomains_controller.rb create行动中我执行所有操作,克隆,生成配置文件,运行rake任务等。在这个create操作中,我需要创建一个具有特定数据库权限的新Mysql用户。

到目前为止我尝试了什么,不能说我做了太多,我试着在控制器创建动作中运行mysql命令:

def create
  if @subdomain.save
    ....
    system "mysql -u root -p root; create database new_database;..."
    ....
  else
    ....
  end
end

但这会使我的创建操作暂停,直到我输入密码,即使我找到了解决方法,我也不确定其余的mysql命令是否可行。可能有一种更好的方法来添加一个命令行的Mysql用户,而无需进入mysql控制台。

谢谢。

2 个答案:

答案 0 :(得分:2)

据我所知,你的create方法在带有root mysql用户的Rails应用程序下运行。 然后你可以通过AR适配器简单地执行mysql命令:

# Create DB
ActiveRecord::Base.connection.execute("CREATE DATABASE IF NOT EXISTS \
`#{ActiveRecord::Base.sanitize(db_name)}` CHARACTER SET = `utf8` \ 
COLLATE = `utf8_general_ci`")    
# Create User
ActiveRecord::Base.connection.execute("REPLACE INTO mysql.user \ 
(Host, User, Password) VALUES(\"localhost\", \ 
\"#{ActiveRecord::Base.sanitize(db_user)}\", \ 
PASSWORD(\"#{ActiveRecord::Base.sanitize(db_password)}\"))")
# Grant access
ActiveRecord::Base.connection.execute("GRANT ALL PRIVILEGES ON \ 
`#{ActiveRecord::Base.sanitize(db_name)}`.* TO \ 
`#{ActiveRecord::Base.sanitize(db_user)}`")
# Apply 
ActiveRecord::Base.connection.execute("FLUSH PRIVILEGES")

答案 1 :(得分:1)

感谢Yuriy的回答,我让它以更短的方式工作:

  def create_mysql_user
    @db_name = "#{@subdomain.name}_domain_production"
    @db_user = "#{@subdomain.name}_user"
    @db_password = "#{@subdomain.name}domain_password"

    ActiveRecord::Base.connection.execute("GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, ALTER,
        INDEX ON `#{@db_name}`.* TO #{ActiveRecord::Base.sanitize(@db_user)}@localhost
        IDENTIFIED BY #{ActiveRecord::Base.sanitize(@db_password)};")
    # Apply
    ActiveRecord::Base.connection.execute("FLUSH PRIVILEGES")
  end
相关问题