阅读之后你甚至不知道JS和JavaScript:Core我仍然无法理解下面代码的行为.
为什么,当我调用时counter()(),我没有得到闭包,但是如果我给结果分配一个变量counter(),比如var getClosure = counter(),我在调用时得到一个闭包getClosure()?
function counter() {
var _counter = 0;
function increase() { return _counter++ }
return increase;
}
// Double ()() to call the returned function always return 0, so no closure.
counter()() // returns 0
counter()() // returns 0
counter()() // returns 0
counter()() // returns 0
var createClosure = counter();
createClosure() // returns 0
createClosure() // returns 1
createClosure() // returns 2
createClosure() …Run Code Online (Sandbox Code Playgroud) 任何人都可以告诉我如何在rails 3中过滤掉之前的所有过滤器.
在rails 2.x中我们可以做到
skip_filter filter_chain
Run Code Online (Sandbox Code Playgroud)
但是rails 3中不再支持filter_chain.
谢谢
假设我需要确保ModelName两个不同的Rails线程不能同时更新; 例如,当发布到应用程序的webhooks尝试在运行某些其他代码的同时修改它时,就会发生这种情况.
Per Rails文档,我认为解决方案是使用model_name_instance.with_lock,也开始新的事务.
这样可以正常工作并防止同时向模型更新,但它不会阻止其他线程在with_lock块运行时读取该表行.
我可以with_lock通过这样做来证明这并不妨碍其他READS:
打开2个导轨控制台;
在控制台1上键入类似的内容 ModelName.last.with_lock { sleep 30 }
在控制台2上,键入ModelName.last.你将能够阅读模型没有问题.
在控制台2上,键入ModelName.update_columns(updated_at: Time.now).您将看到它将在等待30秒锁定到期之前到期.
这证明锁不会阻止读取,据我所知,没有办法锁定数据库行被读取.
这是有问题的,因为如果2个线程在同一时间运行相同的方法,并且我必须决定运行with_lock关于模型数据的某些先前检查的块,则线程2可能正在读取将很快被线程1更新的过时数据在它完成with_lock已经运行的块之后,因为线程2 with_lock在线程1中的块正在进行时CAN读取模型,它只能因为锁定而无法更新它.
编辑:我找到了这个问题的答案,所以你可以在这里停止阅读并直接进入下面:)
我的一个想法是开始with_lock阻止对模型发出无害更新(model_instance_name.update_columns(updated_at: Time.now)例如),然后用a跟随它以model_name_instance.reload确保它获得最新的数据.因此,如果两个线程同时运行相同的代码,则只有一个线程能够发出第一个更新,而另一个线程需要等待释放锁定.一旦它被释放,它将遵循以model_instance_name.reload确保获得由另一个线程执行的任何更新.
问题是这个解决方案对我来说似乎过于苛刻,而且我不确定我应该在这里重新发明轮子(我不知道我是否缺少任何边缘情况).如何确保当两个线程在同一时间运行完全相同的方法时,一个线程等待另一个线程完成甚至读取模型?
我在我的Rails应用程序User中有一个名为的Model ,它有一个属性name
比方说,我想找到的所有Users其name特定的字符串相匹配.
在Rails控制台中,我可以这样做:
选项1
User.where("name LIKE 'string'")
这非常快.
方案2
User.select{|u| u.name == "string"}
这非常慢.它适用于一个小型数据库,但如果你有数十万用户,这似乎首先尝试将所有用户加载Users到内存中,然后在块中迭代它们.
这是否意味着选项2总是错误的?什么是正确的用例.select,什么时候更好.where?
我在我的应用程序中编写了一堆代码正常使用.select,但现在我尝试在一个非常大的表上使用我看到我可能做错了什么.
我们按照 Google Cloud SQL 指令转储了我们的表,并将其导入到第二代 Google Cloud SQL 实例中。
我们很高兴看到我们的数字将如何在“谷歌硬件”上运行。
在使用 Apache 对我们的 Rails 应用程序进行压力测试之后 ab并看到完成时间高 150 毫秒后,我们注意到 ActiveRecord 在相同页面中比我们的生产服务器(裸机)多花费 30 毫秒到 50 毫秒。
当我们深入挖掘时,真正让我们大吃一惊的是像这样的简单计数查询:
GOOGLE CLOUD SQL - db-n1-standard-4 (4vcpu and 15GB RAM)
1. Cold query
mysql> SELECT COUNT(*) FROM `event_log`;
+----------+
| COUNT(*) |
+----------+
| 3998050 |
+----------+
1 row in set (19.26 sec)
2. Repeat query
mysql> SELECT COUNT(*) FROM `event_log`;
+----------+
| COUNT(*) |
+----------+
| 3998050 |
+----------+
1 row in set (1.16 …Run Code Online (Sandbox Code Playgroud) 我正在使用Rails 5.2.0和Webpacker gem来部署Vue应用程序。
show.html.erb文件非常简单:
<div data-behavior="vue-app"><MyComponent></MyComponent></div>
然后在我的入门包中,包是packs / my_vue_app.js:
import TurbolinksAdapter from 'vue-turbolinks';
import Vue from 'vue/dist/vue.esm'
Vue.use(TurbolinksAdapter);
import MyComponent from '../components/my_app/index.vue'
document.addEventListener('turbolinks:load', () => {
var element = $('[data-behavior="vue-app"]');
if(!element) { return };
console.log('Initializing Vue');
const app = new Vue({
el: element[0],
data: {
},
components: { MyComponent }
})
})
Run Code Online (Sandbox Code Playgroud)
在开发中,一切正常。该应用程序已安装且正常运行。
但是在生产中,在页面加载和JS运行之后,<div data-behavior="vue-app">将从分页中删除,仅保留<!-- -->在原处。
在控制台中,绝对没有错误。我可以使用DevTools确认pack js文件已加载并已解析,因为console.log已打印在控制台中。
哎呀,Vue运行正常的证明是,在<div>解析JS之后,已从DOM中删除了整个安装位置。
最奇怪的是,我可以通过在console.log行上附加调试器并在调试器暂停执行时将其关闭来使应用程序挂载ONCE。即使当时我看到应用程序正在安装也很艰难,但后来却无法安装它,甚至再也不用调试器了……这真的非常奇怪。
这些是package.json的版本:
"vue": "^2.5.16",
"vue-loader": "14.2.2",
"vue-template-compiler": "^2.5.16",
Rails应用程序是全新的,除了默认设置外没有其他配置。
Webpacker gem是3.5.3,Rails是5.2.0。
在此上花了很长时间之后,我才发现以下github问题:https : //github.com/rails/webpacker/issues/1520 …
假设我们有一个简单的搜索表单,它提交一个用于搜索/过滤的 GET 请求:
<%= form_with(scope: :search, url: url_for, local: false, method: :get) do |f| %>
<%= f.text_field :title %>
<% end %>
Run Code Online (Sandbox Code Playgroud)
当我们使用form_with(或旧的form_for)ActiveRecord 对象时,所有字段都会自动预先填充 AR 对象属性的当前值。
但在上面的示例中,如果我们仅使用范围(在本例中为search),则当我们使用如下 URL 打开页面时,不会发生这种情况:
http://localhost:3000/blog?search%5title%5D=test
即使 URL 很难为我们填充 Rails params[:search],{title: 'test'}它仍然需要手动传递每个字段的值,如下所示:
<%= f.text_field :title, value: params.dig(:search, :title) %>
随着搜索表单的增长,这变得非常乏味且容易出错,并且这似乎是一个常见的要求,我无法相信没有一种更“轨道的方式”可以在不诉诸表单对象设计模式之类的情况下做到这一点。
是否有任何自动方法可以预先填充这些输入,而不必从参数手动传递值?
我们创建了一个简单的 MobX 存储来保存对象。每次 fooObject 更改时,此 MobX 存储也会与 AsyncStorage 同步:
import { observable } from 'mobx';
class FooStore {
@observable fooObject = {};
setFooObject(newFooObject) {
this.fooObject = newFooObject;
this.syncWithAsyncStorage();
}
syncWithAsyncStorage() {
AsyncStorage.setItem('fooObject', JSON.stringify(this.fooObject));
}
Run Code Online (Sandbox Code Playgroud)
然后,应用程序中的各个屏幕都会使用此 mobx 商店。
正如您所看到的,我们使用 RNAsyncStorage来始终存储 的当前状态,RN 是一种 LocalStorage,但对于本机应用程序而言fooObject。
问题是:当应用程序关闭时,我们会丢失 FooStore 状态,因此我们想要检索对 AsyncStorage 所做的最后一次“保存”(已持久保存)。
问题是 AsyncStorage(正如其名称所示)是一个 ASYNC 函数,我们不能等待 FooStore 构造函数中的承诺解析。
如何根据 AsyncStorage 解析的返回值来完成此 MobX 存储的初始状态初始化?
我们考虑在 FooStore 中编写一个初始化方法(异步方法),如下所示:
async initializeFromAsyncStorage() {
this.fooObject = await JSON.parse(await AsyncStorage.getItem('fooObject'));
}
Run Code Online (Sandbox Code Playgroud)
然后在我们的根 App.js 中的应用程序初始化时调用此方法。
但我不确定这是否会带来意想不到的副作用,以及这是否是惯用的 mobx/react-native。
给定一个 User 类:
class User
end
Run Code Online (Sandbox Code Playgroud)
我想使用.class_eval. 所以:
User.class_eval { AVOCADO = 'fruit' }
Run Code Online (Sandbox Code Playgroud)
如果我尝试通过 访问它User::AVOCADO,我得到uninitialized constant User::AVOCADO,但User.const_get(:AVOCADO)有效。为什么?
如果我在included方法中的 Rails 关注中定义一个常量并将关注包含在User类中,我可以通过常规::查找访问它。例如:
module FruitConcern
extend ActiveSupport::Concern
included do
AVOCADO = 'fruit'
end
end
class User
include FruitConcern
end
User::AVOCADO
=> 'fruit'
Run Code Online (Sandbox Code Playgroud)
但是,查找ActiveSupport::Concern的源代码,included只需将该块存储在实例变量 ( @_included_block) 中,然后它append_features就会覆盖will call base.class_eval(&@_included_block)。
那么,如果它只是User.class_eval使用同一个块调用,为什么User::AVOCADO在该included块内定义常量时有效,而当我User.class_eval { AVOCADO = 'fruit' …
我正处于将 Rails 应用程序从 Turbolinks/rails-ujs(使用产生奇迹的良好 ol 视图)迁移到 Hotwire/Turbo 的早期阶段js.erb。
想象一个users/index.html.erb带有搜索表单和结果表的传统页面:
<%= form_with(scope: :search, url: url_for, method: :get, data: { turbo_frame: "users_table" }) do |f| %>
<%= f.search_field :name %>
<% end %>
<%= turbo_frame_tag("users_table") do %>
<% @users.each do |user| %>
<%= link_to user.name, user, target: :_top %>
<% end %>
<%== pagy_bootstrap_nav(@pagy) %>
<% end %>
Run Code Online (Sandbox Code Playgroud)
因此,上面的搜索表单可以更新下面的 Turbo_frame_tag,而无需重新加载整页(这可以根据需要保留表单中的焦点和状态)。
Turbo_frame_tag 内的每个链接都应导航到 /users/show,替换整个页面。由于target: :_top每个链接中都包含该属性,因此它有效。
然而,用户体验却受到了影响。使用 Turbolinks,users_table 内的每个链接都会发出 AJAX 导航,取代“正文”,感觉非常非常敏捷。使用 Turbo/Hotwire,我可以在开发工具中看到,只有分页(在 Turbo 框架内)和表单提交(由于 Turbo_frame 属性)正在使用 获取fetch …
我有一个使用 Turbolinks 的 Rails 应用程序。如果您不熟悉,turbolinks 会使document和window对象始终保持不变(页面永远不会刷新),并且它会通过 AJAX 拦截所有链接点击并替换 body 标记。
当在安装了 Vue 应用程序的页面之间导航时,这是我们观察到的内存/节点模式(它会增长到无穷大):
正如您所看到的,在每次页面更改时,内存只会增加,而不会被回收。
我们的应用程序使用https://github.com/jeffreyguenther/vue-turbolinks,基本上是这样的代码:
beforeMount: function() {
if (this === this.$root && this.$el) {
document.addEventListener('turbolinks:visit', function teardown() {
this.$destroy();
document.removeEventListener('turbolinks:visit', teardown);
})
// cache original element
this.$cachedHTML = this.$el.outerHTML;
// register root hook to restore original element on destroy
this.$once('hook:destroyed', function() {
if( this.$el.parentNode )
this.$el.outerHTML = this.$cachedHTML
});
}
}
Run Code Online (Sandbox Code Playgroud)
我在 Vue 应用程序上或其他任何地方都没有任何参考window(实例化代码只是new Vue({ options});没有全局变量,使用 const/let 的现代代码。
没有 …
activerecord ×2
javascript ×2
vue.js ×2
closures ×1
hotwire ×1
mobx ×1
mysql ×1
react-native ×1
ruby ×1
turbolinks ×1
webpack ×1
webpacker ×1