这更像是"为什么这样做的事情"这个问题,而不是"我不知道该怎么做"这个问题......
所以关于拉动你知道你将要使用的相关记录的福音就是使用,:include因为你将获得一个连接并避免一大堆额外的查询:
Post.all(:include => :comments)
Run Code Online (Sandbox Code Playgroud)
但是,当您查看日志时,没有发生加入:
Post Load (3.7ms) SELECT * FROM "posts"
Comment Load (0.2ms) SELECT "comments.*" FROM "comments"
WHERE ("comments".post_id IN (1,2,3,4))
ORDER BY created_at asc)
Run Code Online (Sandbox Code Playgroud)
它正在采取一种捷径,因为它会立即提取所有注释,但它仍然不是连接(这是所有文档似乎都说的).我可以获得连接的唯一方法是使用:joins而不是:include:
Post.all(:joins => :comments)
Run Code Online (Sandbox Code Playgroud)
日志显示:
Post Load (6.0ms) SELECT "posts".* FROM "posts"
INNER JOIN "comments" ON "posts".id = "comments".post_id
Run Code Online (Sandbox Code Playgroud)
我错过了什么吗?我有一个有六个关联的应用程序,在一个屏幕上我显示所有这些数据.似乎最好有一个加入查询而不是6个人.我知道在性能方面,进行连接而不是单个查询并不总是更好(事实上,如果你花费时间,看起来上面的两个单独的查询比连接更快),但是在所有文档之后我一直在阅读,我很惊讶地看到:include不像宣传的那样工作.
也许Rails的是认识到性能问题,并除非在某些情况下,不加入呢?
处理一个小的Ruby脚本,该脚本可以访问Web并抓取各种服务.我有一个包含几个类的模块:
module Crawler
class Runner
class Options
class Engine
end
Run Code Online (Sandbox Code Playgroud)
我想在所有这些类中共享一个记录器.通常我只是将它放在模块中的常量中并像这样引用它:
Crawler::LOGGER.info("Hello, world")
Run Code Online (Sandbox Code Playgroud)
问题是,在我知道输出的位置之前,我无法创建我的记录器实例.您可以通过命令行启动爬网程序,此时您可以告诉它您要在开发中运行(日志输出转到STDOUT)或生产(日志输出转到文件,crawler.log):
crawler --environment=production
Run Code Online (Sandbox Code Playgroud)
我有一个类Options解析通过命令行传入的选项.只有在那时我才知道如何使用正确的输出位置实例化记录器.
所以,我的问题是:我如何/在哪里放置我的记录器对象,以便我的所有类都可以访问它?
我可以将我的记录器实例传递给new()我创建的每个类实例的每个调用,但我知道必须有一个更好的Rubyish方法来实现它.我正在想象与模块共享的一些奇怪的类变量class << self或其他魔法.:)
更多细节:Runner通过将命令行选项传递给Options类来启动所有内容,并获取具有几个实例变量的对象:
module Crawler
class Runner
def initialize(argv)
@options = Options.new(argv)
# feels like logger initialization should go here
# @options.log_output => STDOUT or string (log file name)
# @options.log_level => Logger::DEBUG or Logger::INFO
@engine = Engine.new()
end
def run
@engine.go
end
end
end
runner = Runner.new(ARGV)
runner.run
Run Code Online (Sandbox Code Playgroud)
我需要代码Engine …
所以我试图通过RVM作为服务运行.后一个thin install我手动更新/etc/init.d/thin使用一个su - user运行的配置命令时,使薄正在运行作为本地用户,而不是根.到现在为止还挺好.
现在,当我尝试sudo service thin start它时,它似乎正在尝试使用非RVM版本的Ruby(安装在盒子上的1.8.7开始)来实际执行命令.我gem install thin在非RVM版本上做了一个,然后给我一个uninitialized constant Bundler消息 - Bundler只安装在RVM宝石中,而不是系统宝石.看起来我无法设置RVM环境(即使我的RVM启动脚本在〜/ .bashrc中,然后包含在〜/ .bash_profile中).
我想要做的就是使用RVM环境而不是系统环境作为服务运行.这甚至可能吗?我应该放弃并承诺以root身份运行一切的最终罪行吗?这一点非常诱人.
谢谢你的帮助!
所以将USR2发送到Unicorn是非常棒的 - 它会启动一个带有新代码副本的新主服务器并自动获取任何更改.甜.我的问题是:我如何阻止老主人?显而易见的方式是在before_fork中:
before_fork do |server,worker|
old_pid = '/var/www/current/tmp/pids/unicorn.pid.oldbin'
if File.exists?(old_pid) && server.pid != old_pid
begin
Process.kill("QUIT", File.read(old_pid).to_i)
rescue Errno::ENOENT, Errno::ESRCH
# someone else did our job for us
end
end
end
Run Code Online (Sandbox Code Playgroud)
这个问题是,一旦新的主人(和新工人)被催生,他们就会杀死旧的主人.因此,对网站的任何请求都只是坐在那里等待新工作人员启动,通常在整个Rails堆栈加载时持续几秒钟.
如果我删除了我的before_fork一切正常,我希望(从客户端的角度来看):我可以整天重新加载我的浏览器,并且每个请求都快速填写,没有任何迹象表明新主人何时接管(除了看到我的代码)现在出现变化).但是,老主人现在一直挂着,直到我手动发送一个退出.
据我所知,一旦工人完成装载并准备为客户服务,就没有回调.这真的是我正在寻找的回调.我总是可以在Rails中创建一个初始化程序,它可以找到一个老主人并杀死它,但这只会让我心疼.
一定有办法!
有人发现是否可以将终端实例"嵌入"到应用程序中?如果它还继承了标签功能和拖放功能,那将是非常棒的.我在这里看到了几个类似的问题,提到iTerm,但似乎应该有一个更简单的方法.像NSTerminal对象一样,我可以进入视图.
我问恐慌的人这件事.他们在Coda中有一个终端窗口,用于所有意图和目的,其外观/功能与在桌面上独立运行的Terminal.app完全相同.然而,他们的反应是他们必须从头开始自己写.我希望有人找到更好的方法!
谢谢!
所以我有一个使用CouchDB作为后端的应用程序.Couch还没有真正拥有它的安全/用户模型,默认情况下任何人都可以做任何事情(包括删除记录甚至整个数据库).但是,如果我们限制只访问GET请求,我们会更安全.
我希望我可以将nginx作为反向代理放在前面,但是我找不到一个允许你根据动词过滤请求的选项.庞德这样做所以我想要走这条路,但我们已经广泛使用nginx,不要在混合中添加其他技术.任何人都知道是否有一个可以让这种情况发生的选择?
我甚至会在Apache中找到一个mod_proxy选项.有任何想法吗?
因此,Ruby的守护进程gem允许您monitor=true在启动进程时进行设置.什么是监视器,你用它做什么?你所做的只是指定true或false...是在某处创建一个日志文件?实际监控过程的东西,比如god?为什么关于这件东西如此可怕的文件呢?
或者这实际上是每个人都应该知道的Unix事情?:)
我不知道为什么会发生这种情况,但Rails将字符串保存为SQLite作为BLOB.在我的应用程序中创建新用户之前,我在保存到数据库之前使用其纯字符串密码和MD5:
class User < ActiveRecord::Base
before_create :encrypt_password
def encrypt_password
self.password = Digest::MD5.hexdigest(self.password)
end
end
Run Code Online (Sandbox Code Playgroud)
但是,密码字段每次进入SQLite都是一个疯狂的BLOB!我甚至可以告诉的唯一方法是将表导出到SQL时我可以看到该字段的真实性质:
INSERT INTO "users" VALUES (24, 'john.doe@example.com', X'3639366432396530393430613439353737343866653366633965666432326133');
Run Code Online (Sandbox Code Playgroud)
我勒个去??所以现在当我尝试通过查找他们的电子邮件和MD5哈希密码来验证用户时,它每次都会失败.REAL字符串显然与BLOB不匹配:
User.find_by_email_and_password('john.doe@example.com', Digest::MD5.hexdigest('password') => nil
Run Code Online (Sandbox Code Playgroud)
我一生中从未使用BLOB,更不用说作为用户表的密码字段了.我的迁移明确定义:string为数据类型.做一个User.columns清楚地显示:
#<ActiveRecord::ConnectionAdapters::SQLiteColumn:0x00000105256ce0 @name="password", @sql_type="varchar(255)"
Run Code Online (Sandbox Code Playgroud)
我一直在为这个应用程序工作一个月的大部分时间,直到昨晚我为User模型编写一些测试时才会看到这个问题.尝试对用户进行身份验证的测试每次都会失败,因此我开始在控制台中手动构建用户,并发现密码永远不会匹配,因此所有用户查找都会失败.
用于创建用户的Rails调试信息如下所示:
INSERT INTO "users" ("created_at", "email", "first_name", "last_login_at", "last_name", "login_count", "password", "role_id", "twitter", "updated_at", "uuid") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) [["created_at", Mon, 04 Jul 2011 18:50:58 UTC +00:00], ["email", "braulio_towne@runolfsson.name"], ["first_name", "Ebba"], ["last_login_at", nil], ["last_name", "Bayer"], ["login_count", …Run Code Online (Sandbox Code Playgroud) 我的应用程序中有一个Rails引擎.这是它挂钩到我的routes.rb文件:
Mercury::Engine.routes
Run Code Online (Sandbox Code Playgroud)
我试图限制访问引擎提供的URL,所以我尝试使用约束:
class EditorRestrictor
def self.matches?(request)
false
end
end
constraints EditorRestrictor do
Mercury::Engine.routes
end
Run Code Online (Sandbox Code Playgroud)
但引擎的路线仍然可以访问.我重新启动了我的应用以防万一,但没关系.有任何想法吗?
使用JBuilder时,如何从输出中完全删除空数组元素的证据?对于此代码示例,假设我们有三个用户,第三个用户有一个nil地址:
json.array! @users.each do |user|
unless user.address.nil?
json.name user.name
json.address user.address
end
end
Run Code Online (Sandbox Code Playgroud)
生成的JSON是:
[
{
"name":"Rob",
"address":"123 Anywhere St."
},
{
"name":"Jack",
"address":"123 Anywhere St."
},
{}
]
Run Code Online (Sandbox Code Playgroud)
看到最后一个,{}那里到底是空的.因此,只要块传递给array!返回,nil我最终会在数组中使用空元素,而不是缺少元素.有没有简单的方法告诉JBuilder不输出那些?或者我只需要将输出array!视为一个简单的数组然后compact或者reject我不想要的元素?
我有一个使用Devise进行身份验证的应用程序.登录字段位于主页上.如果我打开两个选项卡(选项卡A和选项卡B,然后手动注销每个选项卡(第一个选项卡A,然后选项卡B),然后返回选项卡A并尝试登录,我收到InvalidAuthenticityToken错误.
然后我可以回到选项卡B并尝试登录并获取错误.然后返回选项卡A并尝试登录并再次获取错误.这将无限期地发生,直到您在同一选项卡中获取InvalidAuthenticityToken错误后立即尝试登录选项卡.
我可以在ApplicationController中设置以下内容:
protect_from_forgery :with => :null_session
Run Code Online (Sandbox Code Playgroud)
但是现在第一次登录尝试将返回到主页,但没有指出您的登录失败的原因(您只是再次看到主页而不是InvalidAuthenticityToken错误页面).如果您再尝试再次登录(在同一选项卡上),则会成功.
而且我知道它为什么会发生:会话正在重置登出时重置csrf_token会话.第二个选项卡重置该标记,但第一个选项卡仍然具有前一个标记.因此,当第一个选项卡提交表单时,该表单csrf_token无效.
我可以在服务器端做什么吗?或者我将不得不做一些疯狂的解决方法,比如在你注销时在localStorage中设置一些东西,或者打开一个websocket,这样我就会在主页上通知另一个选项卡重置了CSRF令牌?
让一个打开多个标签的用户通过每个标签并手动注销似乎是一种罕见的情况,但这只是模拟网站的实际行为:10分钟后自动将其记录下来.这在我们的应用程序中经常发生.
我正在使用Capistrano部署Rails 3应用程序.我已经在远程服务器(以及本地)上运行RVM,而Bundler正在管理我的所有宝石.这是问题所在:
部署时,Capistrano运行以下命令:
bundle install --gemfile /var/www/releases/20110301225633/Gemfile --path /var/www/shared/bundle --deployment --quiet --without development test
Run Code Online (Sandbox Code Playgroud)
所以,我所有的宝石都在/var/www/shared/bundle,好的.但是,这意味着系统路径中没有安装任何宝石(即,运行不gem list返回任何内容),因此我不能使用任何可能与这些宝石一起提供的bin文件,包括rails命令本身.我能够启动Web服务器(瘦)的唯一方法是手动gem install thin.一旦薄的卷轴,它就可以很好地启动Rails,包括所有必需的宝石.
那么,如何在正在运行的应用程序之外访问这些宝石?我知道我不应该手动安装任何东西来使这个工作,但我不知道我错过了什么.我尝试过运行,rvm-shell '1.9.2@mygemset' -c 'thin start'但是我遇到了与尝试thin start直接从命令行调用相同的错误:bash: thin: command not found即使直接进入bundler的bin目录/var/www/shared/bundle/bundle/ruby/1.9.1/bin来启动瘦也会给我带来同样的错误.
我觉得RVM应该为我照顾这个......也许有一个环境变量我不见了?
谢谢你的帮助!