Home Php C# Sql C C++ Javascript Python Java Go Android Git Linux Asp.net Django .net Node.js Ios Xcode Cocoa Iphone Mysql Tomcat Mongodb Bash Objective-c Scala Visual-studio Apache Elasticsearch Jar Eclipse Jquery Ruby-on-rails Ruby Rubygems Android-studio Spring Lua Sqlite Emacs Ubuntu Perl Docker Swift Amazon-web-services Svn Html Ajax Xml Java-ee Maven Intellij-idea Rvm Macos Unix Css Ipad Postgresql Css3 Json Windows-server Vue.js Typescript Oracle Hibernate Internet-explorer Github Tensorflow Laravel Symfony Redis Html5 Google-app-engine Nginx Firefox Sqlalchemy Lucene Erlang Flask Vim Solr Webview Facebook Zend-framework Virtualenv Nosql Ide Twitter Safari Flutter Bundle Phonegap Centos Sphinx Actionscript Tornado Register | Login | Edit Tags | New Questions | 繁体 | 简体


10 questions online user: 29

0
votes
answers
10 views
+10

Match all occurrences of a regex

Is there a quick way to find every match of a regular expression in Ruby? I've looked through the Regex object in the Ruby STL and searched on Google to no avail.

0
votes
answers
63 views
+10

Rails - 使用ActiveRecord :: Enum的參數錯誤

2

我創建了一個模型Tester,整數列爲tester_type,並聲明模型中的enum變量。Rails - 使用ActiveRecord :: Enum的參數錯誤

class Tester < ApplicationRecord 
    enum tester_type: { junior: 0, senior: 1, group: 2 } 
end 

我得到以下錯誤,而試圖創建/初始化該模型中的對象:

ArgumentError: You tried to define an enum named "tester_type" on the model "Tester", but this will generate a class method "group", which is already defined by Active Record.

所以,我試圖改變tester_typetype_of_tester但它拋出同樣的錯誤:

ArgumentError: You tried to define an enum named "type_of_tester" on the model "Tester", but this will generate a class method "group", which is already defined by Active Record.

我已經搜索的解決方案,我發現這個錯誤是一個常數ENUM_CONFLICT_MESSAGEActiveRecord::Enum類,但不能夠找到這個問題的原因。

請幫幫我。

謝謝。

+0

更改emum的名稱,不要使用testers_type這已被rails使用。 – Sunny

+0

我試着將它改爲'type_of_tester',但是它拋出了相同的錯誤。 –

+0

你也可以粘貼該錯誤。 – Sunny

沙发
0
2

在這種情況下,如果你想使用枚舉,你最好將你的標籤重命名爲其他東西。這不僅限於枚舉 - 許多Active Record功能爲您生成方法,通常也沒有辦法選擇退出這些生成的方法。

然後更改groupanother_name

還是應該遵循這也

enum :kind, [:junior, :senior, :group], prefix: :kind 
band.kind_group? 
板凳
0
1

檢查了這一點。它是您遇到問題的選項組。您可以使用前綴選項,因爲在這個崗位

enum options

地板
0
1

提到可以使用:_prefix:_suffix選擇,當你需要定義具有相同的價值觀或你的情況多枚舉,以避免與已定義的方法發生衝突。如果傳遞值爲true,則方法前綴/後綴爲枚舉的名稱。另外,也可以提供一個自定義的值:

class Conversation < ActiveRecord::Base 
    enum status: [:active, :archived], _suffix: true 
    enum comments_status: [:active, :inactive], _prefix: :comments 
end 

採用上述例子中,爆炸和與相關聯的範圍沿着謂詞方法現在前綴和/或相應後綴:

conversation.active_status! 
conversation.archived_status? # => false 

conversation.comments_inactive! 
conversation.comments_active? # => false 

爲了您情況下,我的建議是使用類似:

class Tester < ApplicationRecord 
    enum tester_type: { junior: 0, senior: 1, group: 2 }, _prefix: :type 
end 

然後你就可以使用這些範圍爲:

tester.type_group! 
tester.type_group? # => true 

Tester.type_group # SELECT "testers".* FROM "testers" WHERE "testers"."tester_type" = $1 [["tester_type", 2]] 
# or, 
Tester.where(tester_type: :group) # SELECT "testers".* FROM "testers" WHERE "testers"."tester_type" = $1 [["tester_type", 2]] 
0
votes
answers
58 views
+10

紅寶石插座 - 運行在socker上的方法

1

我是Ruby插座中的新手。我在服務器項目,我坐了起來插座的服務器如下:紅寶石插座 - 運行在socker上的方法

require 'socket'    
server = TCPServer.open(2000)  
loop {       
    Thread.start(server.accept) do |client| 
    client.puts(Time.now.ctime) 
    client.puts "Closing the connection. Bye!" 
    client.close     
end 

我想從客戶端運行我的方法之一,在我的項目:

require 'socket'  

hostname = 'localhost' 
port = 2000 

s = TCPSocket.open(hostname, port) 

while line = s.gets  
    puts line.chop  
    puts "hey" 

    # call helloWorldMethod() 
end 

s.close     
沙发
0
0
require 'socket'    
server = TCPServer.open(2000)  
loop do       
    Thread.start(server.accept) do |client| 
    client.puts(Time.now.ctime) 
    client.puts "Closing the connection. Bye!" 
    client.close     
    end 
end 

我相信您的解決方案是在??

,我發現這個文檔中關於ruby socket programming

微型網頁瀏覽器

我們可以使用套接字庫來實現任何Internet協議。這裏,例如,是抓取網頁

取決於你的路由你可能要調整URL的內容的代碼,它chould是www.yourwebsite.com/users

require 'socket' 

host = 'www.tutorialspoint.com'  # The web server 
port = 80       # Default HTTP port 
path = "/index.htm"     # The file we want 

這是HTTP請求我們發送獲取文件

,您可以在HTTP postput要求

改變你的要求
request = "GET #{path} HTTP/1.0

" 

socket = TCPSocket.open(host,port) # Connect to server 
socket.print(request)    # Send request 
response = socket.read    # Read complete response 
# Split response at first blank line into headers and body 
headers,body = response.split("

", 2) 
print body       # And display it 

要實現類似的Web客戶端,您可以使用像Net :: HTTP這樣的預建庫來處理HTTP。以下是代碼,代碼相當於以前的代碼 -

require 'net/http'     # The library we need 
host = 'www.tutorialspoint.com'  # The web server 
path = '/index.htm'     # The file we want 

http = Net::HTTP.new(host)   # Create a connection 
headers, body = http.get(path)  # Request the file 
if headers.code == "200"   # Check the status code 
    print body       
else         
    puts "#{headers.code} #{headers.message}" 
end 
0
votes
answers
55 views
+10

在瀏覽器中調用oAuth2 api時出現404錯誤

4

我在rails上使用ruby來製作RESTful API,並且還使用門衛來處理身份驗證和授權。正如你所知,門衛生成一些OAuth2 api,而我需要使用的其中兩個是/用戶,這是發送請求和/ oauth /令牌爲我製作令牌。我製作的api,post,get,put作品在郵遞員和android工作室以及網頁瀏覽器中都有。 但門衛生成的post api/users和/ oauth/token在web瀏覽器中不起作用,但在android studio和postman上效果很好。 這讓我感到困惑。我在調用這個api時遇到的錯誤是404,我檢查了服務器上的ruby生產日誌,並且它說沒有路由匹配。這裏的字符串的東西是方法和路線的類型是正確的。在瀏覽器中調用oAuth2 api時出現404錯誤

這是我在reactjs中使用的代碼。我用axios:

var url="http://x.x.x.x/oauth/token"; 
    axios.post(url,{ 
     "username":"1", 
     "password":"password", 
     "grant_type":"password" 
     },{headers:{"Content-Type":"application/json"}}).then((response) => { 
      console.log(response.data); 
     }) 
     .catch((error) => { 
      console.log(JSON.stringify(error)); 
     }); 

而且還使用原始jQuery發出請求並獲得相同的錯誤。我所有的API運作良好execpt這兩個API:

var firstname = document.forms["registerForm"]["first_name"].value; 
    var lastname = document.forms["registerForm"]["last_name"].value; 
    var pass = document.forms["registerForm"]["password"].value; 
    var passconfirm = document.forms["registerForm"]["password_confirmation"].value; 


    var json_data = { 
     "async": true, 
     "crossDomain": true, 
     "url": send, 
     "method": "POST", 
     "headers": { 
      "content-type": "application/json", 
     }, 
     "processData": false, 
     "data": 
     { 
      "user": { 
       "user_name": username, 
       "password": pass, 
       "password_confirmation": passconfirm, 
       "user_type": "admin" 
      }, 
      "profile": { 
       "first_name": firstname, 
       "last_name": lastname 
      } 
     } 
    } 

    $.ajax(json_data).done(function (response) { 
     console.log(response); 
    }); 
    console.log(json_data['data']); 
    console.log(username); 

這段代碼的console.log輸出(JSON.stringify(錯誤));是這樣的:

{"config":{"transformRequest":{},"transformResponse":{},"timeout":0,"xsrfCookieName":"XSRF-TOKEN","xsrfHeaderName":"X-XSRF-TOKEN","maxContentLength":-1,"headers":{"Accept":"application/json, text/plain, */*","Content-Type":"application/json;charset=utf-8"},"method":"post","url":"http://x.x.x.x/oauth/token.json","data":"{"username":"1","password":"password","grant_type":"password"}"},"request":{}} 

我找到請求頭和響應頭到瀏覽器:

Response Header: 

Content-Type  
application/json; charset=UTF-8 
Content-Length 
34 
Connection 
keep-alive 
Status 
404 Not Found 
X-Request-Id  
d593b73f-eec8-41cd-95cd-e4459663358c 
X-Runtime 
0.002108 
Date  
Mon, 13 Nov 2017 11:19:26 GMT 
X-Powered-By  
Phusion Passenger 5.1.11 
Server 
nginx/1.12.1 + Phusion Passenger 5.1.11 


Request headers (427 B) 
Host  
x.x.x.x 
User-Agent 
Mozilla/5.0 (X11; Ubuntu; Linu…) Gecko/20100101 Firefox/56.0 
Accept 
text/html,application/xhtml+xm…plication/xml;q=0.9,*/*;q=0.8 
Accept-Language 
en-US,en;q=0.5 
Accept-Encoding 
gzip, deflate 
Access-Control-Request-Method 
POST 
Access-Control-Request-Headers 
Origin 
http://localhost:3000 
Connection 
keep-alive 
+0

你能分享錯誤訊息嗎? – aks

+0

這可能與CORS有關,你可以嘗試使用var'url =「http://x.x.x.x/oauth/token.json」'? – aks

+0

是的,我只是添加json到我的端點結束,但它不工作,也做了這個關於CORS的教程這樣的https://enable-cors.org/server_nginx.html並添加到我的代碼 – Sandro

沙发
0
0

檢查他們docs後,它看起來像你需要改變Content-Typeapplication/x-www-form-urlencoded和數據key=value對:

const data = 'username=1&password=password&grant_type=password'

或者乾脆:

const formData = { 
    username: '1', 
    password: 'password', 
    grant_type: 'password', 
} 

const data = Object.keys(formData) 
    .map(prop => `${prop}=${formData[prop]}`) 
    .join('&') 

最終的結果將是:

var url="http://x.x.x.x/oauth/token"; 

axios.post(url, data, { 
    headers: { 
    "Content-Type": "application/x-www-form-urlencoded" 
    } 
}).then((response) => { 
    console.log(response.data); 
}) 
.catch((error) => { 
    console.log(JSON.stringify(error)); 
}); 
+0

我測試了你的方式,但沒有解決,我在WWW-Authenticate中得到了一個響應,其中描述了Bearer realm =「Doorkeeper」,error =「invalid_request」,error_description =「該請求缺少必需參數,包含不受支持的參數值或者格式錯誤「。 – Sandro

+0

@Sandro他們的文檔也提到發送('grant_type','client_id','client_secret','code' ..)你發送這些道具嗎? – mersocarlin

板凳
0
0

您需要在您的OAuth設置以配置爲允許訪問客戶端的Web應用程序。檢查您在api響應中獲得的日誌或錯誤消息。

+0

@Sandro你有沒有找到任何解決方案? – Fawaz

+1

不,我仍在搜索,其中一名senoir開發人員說,它可以從門衛回調url中,但我不知道如何在門衛中配置回調url。門衛有一些關於回叫的理論文本,但沒有關於它的技術文件。不知道該怎麼做 – Sandro

0
votes
answers
29 views
+10

如何在ruby-vips中實現maxfilter(給定的半徑)?

0

我想做的事情是這樣的:如何在ruby-vips中實現maxfilter(給定的半徑)?

enter image description here

http://reference.wolfram.com/language/ref/MaxFilter.html

比方說我的形象有一個通道(灰度模式)。

沙发
0
0

下面是我如何用PI * R * R卷積來做到的。

R = 2 
D = R + R + 1 
CIRCLE = Vips::Image.black(D, D).draw_circle(1, R, R, R, fill: true).to_a 

new_image = image 
D.times do |i| 
    D.times do |j| 
    next unless CIRCLE[i][j] == [1] 
    t = image.conv Vips::Image.new_from_array Array.new(D){ [0]*D }.tap{ |t| t[i][j] = 1 } 
    new_image = (new_image > t).ifthenelse(new_image, t) 
    end 
end 

return new_image 
板凳
0
0

如果你不介意的方形窗口,你可以用一個排名過濾器做到這一點:

result = image.rank w, h, w * h - 1 

http://jcupitt.github.io/libvips/API/current/libvips-morphology.html#vips-rank

http://www.rubydoc.info/gems/ruby-vips/Vips/Image#rank-instance_method

wh是寬度和窗戶的高度。

當然,最大/最小值是可分離的,所以你也可以這樣寫:

result = image.rank(w, 1, w - 1).rank(1, h, h - 1) 

這將是更快的半徑大。

+0

窗戶形狀當然很重要。雖然這是一個有趣的方法。也許有可能表示一個半徑爲5的圓圈,因爲兩個重疊的3x5和5x3的矩形以某種方式組合了結果。不確定更大的半徑,但這可能比我的方法更快。 – Nakilon

+0

這是一個聰明的想法。你需要爲多大的R工作? – user894763

62
votes
answers
29 views
+10

uninitialized constant Rake::DSL in Ruby Gem

I have been working on updating my gem (whm_xml at https://github.com/ivanoats/whm_xml_api_ruby ) to make it work with ruby 1.9.2, latest rubygems, latest bundler, latest rdoc, latest rake. It works fine in 1.8.7 but has the "uninitialized constant Rake::DSL" error only in 1.9.2 . I thought that rake 0.9.2 fixed that but maybe not? I have read a lot on StackOverflow but am still stuck. Any ideas on where to look?

ivan:~/Development/ruby/whm_xml_api_ruby [git:master+]  → bundle exec rake -T
(in /Users/ivan/Development/ruby/whm_xml_api_ruby)
rake aborted!
uninitialized constant Rake::DSL
/Users/ivan/.rvm/rubies/ruby-1.9.2-p180/lib/ruby/1.9.1/rake.rb:2482:in `const_missing'
/Users/ivan/.rvm/gems/ruby-1.9.2-p180/gems/rake-0.9.2/lib/rake/tasklib.rb:8:in `<class:TaskLib>'
/Users/ivan/.rvm/gems/ruby-1.9.2-p180/gems/rake-0.9.2/lib/rake/tasklib.rb:6:in `<module:Rake>'
/Users/ivan/.rvm/gems/ruby-1.9.2-p180/gems/rake-0.9.2/lib/rake/tasklib.rb:3:in `<top (required)>'
/Users/ivan/.rvm/gems/ruby-1.9.2-p180/gems/rdoc-3.6.1/lib/rdoc/task.rb:37:in `require'
/Users/ivan/.rvm/gems/ruby-1.9.2-p180/gems/rdoc-3.6.1/lib/rdoc/task.rb:37:in `<top (required)>'
/Users/ivan/Development/ruby/whm_xml_api_ruby/Rakefile:3:in `require'
/Users/ivan/Development/ruby/whm_xml_api_ruby/Rakefile:3:in `<top (required)>'
/Users/ivan/.rvm/rubies/ruby-1.9.2-p180/lib/ruby/1.9.1/rake.rb:2373:in `load'
/Users/ivan/.rvm/rubies/ruby-1.9.2-p180/lib/ruby/1.9.1/rake.rb:2373:in `raw_load_rakefile'
/Users/ivan/.rvm/rubies/ruby-1.9.2-p180/lib/ruby/1.9.1/rake.rb:2007:in `block in load_rakefile'
/Users/ivan/.rvm/rubies/ruby-1.9.2-p180/lib/ruby/1.9.1/rake.rb:2058:in    `standard_exception_handling'
/Users/ivan/.rvm/rubies/ruby-1.9.2-p180/lib/ruby/1.9.1/rake.rb:2006:in `load_rakefile'
/Users/ivan/.rvm/rubies/ruby-1.9.2-p180/lib/ruby/1.9.1/rake.rb:1991:in `run'
/Users/ivan/.rvm/gems/ruby-1.9.2-p180/gems/rake-0.9.2/bin/rake:32:in `<top (required)>'
/Users/ivan/.rvm/gems/ruby-1.9.2-p180/bin/rake:19:in `load'
/Users/ivan/.rvm/gems/ruby-1.9.2-p180/bin/rake:19:in `<main>'
up vote 55 down vote accepted favorite
沙发
+550
+50

這個SO問題可能會幫助你。建議在require 'rake/dsl_definition'上面加上require 'rake'你的Rakefile

Thanks, that really helped! – Ivan Jun 7 '11 at 18:12

+30

我認為這是rake 0.9.0版本發生的事情。試著把它放在你的Gemfile中:gem 'rake', '0.8.7'

更新

你可以嘗試添加

include Rake::DSL if defined?(Rake::DSL)

到你的應用程序; 它曾一度適用於我的Rails應用程序。

Yes, that is correct. rake 0.9.2 was supposed to correct this. Also, I want my gem to work with all the latest versions if possible. – Ivan Jun 7 '11 at 17:35

Sorry, I had skimmed over your answer and didn't realize you were aware of that. I updated my answer to try a different method. – Abe Voelker Jun 7 '11 at 18:01

Rake 0.9.2 worked for me. – Ben Fulton Sep 27 '11 at 2:27

+30

我愚弄了包括Rake :: DSL等,並且還有其他錯誤。

加入

寶石'耙','0.8.7'

到Gemfile似乎對我有用

+10

我在0.9.1中遇到了同樣的問題,安裝了0.9.2並且它運行但db:migrate命令發送了一條消息警告:不推薦全局訪問Rake DSL方法。請....它解決了添加到rake文件模塊:: yourappname 類應用程序包括Rake :: DSL end end並在..之前需要'rake / dsl_definition'.LoadTask條目

0
votes
answers
34 views
+10

工廠女孩保留字屬性的關聯

0

工廠女孩文檔建議使用ADD_ATTRIBUTE方法來處理屬於保留字的屬性,具體如下:工廠女孩保留字屬性的關聯

factory :dna do 
    add_attribute(:sequence) { 'GATTACA' } 
end 

但是我有一個名爲特質(這是保留的)模型稱爲ContestantTrait的另一種模型,屬於Trait。我試着用不同的方式使用add_attribute來避免關聯中的保留字問題,但似乎沒有任何工作。

有什麼建議嗎?這是到目前爲止,我已經試過格式:

FactoryGirl.define do 
    factory :contestant_trait do 
    add_attribute(:trait) 
    add_attribute(:trait) {} 
    add_attribute(:trait) {trait} 
    end 
end 
+0

你可以使用新名稱來保留保留字,你應該沒問題。 –

沙发
0
0

沒有必要界定,因爲:trait:add_attribute是一個關聯。使用關鍵字association如下:

FactoryGirl.define do 
    factory :contestant_trait do 
    association :trait 
    # ... other attributes 
    end 
end 

作爲一個側面說明,建議升級到FactoryBot

由於兩個factory_girl和factory_girl_rails的4.9.0版本中,無論是寶石會正式棄用。在4.9.0版本中。

看到這個職位https://robots.thoughtbot.com/factory_bot更多的形成和如何升級。

+0

你能解決你的問題與上述解決方案? – s3tjan

46
votes
answers
52 views
+10

bundle install returns “Could not locate Gemfile”

I'm new to Rails and am currently working through a guide. The guide states:

Use a text editor to update the Gemfile needed by Bundler with the contents of Listing 2.1.

source 'https://rubygems.org'

gem 'rails', '3.2.3'

group :development do
  gem 'sqlite3', '1.3.5'
end


# Gems used only for assets and not required
# in production environments by default.

group :assets do
  gem 'sass-rails',   '3.2.4'
  gem 'coffee-rails', '3.2.2'
  gem 'uglifier', '1.2.3'
end

gem 'jquery-rails', '2.0.0'

group :production do
  gem 'pg', '0.12.2'
end

We then install and include the gems using the bundle install command:

    $ bundle install --without production 

If Bundler complains about no such file to load -- readline (LoadError) try adding gem ’rb-readline’ to your Gemfile.)

I followed the steps even adding on gem 'rb-readline' to the Gemfile, but apparently the file can't be found and when I go to my text editor I do see the Gemfile itself. I noticed that they made me put gem 'rails', 3.2.3 and my version of Rails is 3.2.1 so I tried changing it to 3.2.1 but that didn't work either.

Any thoughts or advice would be much appreciated.

沙发
+180

You may also indicate the path to the gemfile in the same command e.g.

BUNDLE_GEMFILE="MyProject/Gemfile.ios" bundle install
板凳
+140

I had this problem as well on an OSX machine. I discovered that rails was not installed... which surprised me as I thought OSX always came with Rails. To install rails

  • sudo gem install rails
  • to install jekyll I also needed sudo
  • sudo gem install jekyll bundler
  • cd ~/Sites
  • jekyll new <foldername>
  • cd <foldername> OR cd !$ (that is magic ;)
  • bundle install
  • bundle exec jekyll serve
  • Then in your browser just go to http://127.0.0.1:4000/ and it really should be running
地板
+70

You should be in the same directory of Gemfile

4楼
+70

When I had similar problem gem update --system helped me. Run this before bundle install

5楼
0

Search for the Gemfile file in your project, go to that directory and then run "bundle install". prior to running this command make sure you have installed the gem "sudo gem install bundler"

6楼
-80

Think more about what you are installing and navigate Gemfile folder, then try using sudo bundle install

這會產生關於未經檢查的強制轉換的警告。這是安全的嗎? - 2017年10月20日21:16

0
votes
answers
31 views
+10

Difference between a class and a module

I came from Java, and now I am working more with Ruby.

One language feature I am not familiar with is the module. I am wondering what exactly is a module and when do you use one, and why use a module over a class?

49
votes
answers
43 views
+10

How to test ElasticSearch in a Rails application (Rspec)

I was wondering how you were testing the search in your application when using ElasticSearch and Tire.

  • How do you setup a new ElasticSearch test instance? Is there a way to mock it?

  • Any gems you know of that might help with that?


Some stuff I found helpful:

I found a great article answering pretty much all my questions :)

http://bitsandbit.es/post/11295134047/unit-testing-with-tire-and-elastic-search#disqus_thread

Plus, there is an answer from Karmi, Tire author.

This is useful as well: https://github.com/karmi/tire/wiki/Integration-Testing-Rails-Models-with-Tire

I can't believe I did not find these before asking...

up vote 34 down vote accepted favorite
沙发
+340
+50

為當前環境添加索引名稱前綴

您可以為每個環境設置不同的索引名稱(在您的情況下:測試環境)。

例如,您可以在中創建初始化程序

config/initializers/tire.rb

使用以下行:

Tire::Model::Search.index_prefix "#{Rails.application.class.parent_name.downcase}_#{Rails.env.to_s.downcase}"

一種可以想到的刪除索引的方法

假設您有名為Customer,Order和Product的模型,請將以下代碼放在test-startup / before-block / each-run-block的某處。

# iterate over the model types
# there are also ways to fetch all model classes of the rails app automaticly, e.g.:
#   http://stackoverflow.com/questions/516579/is-there-a-way-to-get-a-collection-of-all-the-models-in-your-rails-app
[Customer, Order, Product].each do |klass|

  # make sure that the current model is using tire
  if klass.respond_to? :tire
    # delete the index for the current model
    klass.tire.index.delete

    # the mapping definition must get executed again. for that, we reload the model class.
    load File.expand_path("../../app/models/#{klass.name.downcase}.rb", __FILE__)

  end
end

替代

另一種方法是設置一個不同的ElasticSearch實例來測試另一個端口,比方說1234.在你的enviornment / test.rb中,你可以設置

Tire::Configuration.url "http://localhost:1234"

在適當的位置(例如您的測試啟動),您可以刪除ElasticSearch測試實例上的所有索引:

Tire::Configuration.client.delete(Tire::Configuration.url)

也許您仍然必須確保您的模型類的輪胎映射定義仍然被調用。

+110

在我的rspec套件中通過輪胎刪除我的彈性搜索索引時遇到了一個奇怪的錯誤。在我的Rspec配置中,類似於Bits和Bytes博客,我有一個after_each調用,它清理數據庫並清除索引。

我發現我需要調用Tire的create_elasticsearch_index方法,該方法負責讀取ActiveRecord類中的映射以設置適當的分析器等。我看到的問題是我在我的模型中有一些:not_analyzed字段實際上已被分析(這打破了我想要分面工作的方式)。

開發方面的一切都很好,但測試套件失敗了,因為各個單詞而不是整個多字符串都破壞了方面。刪除索引後,似乎沒有在rspec中正確創建映射配置。添加create_elasticsearch_index調用修復了問題:

config.after(:each) do
  DatabaseCleaner.clean
  Media.tire.index.delete
  Media.tire.create_elasticsearch_index
end

媒體是我的模特課。

+40

我遇到了類似的問題,這就是我解決它的方法。請記住,我的解決方案建立在@spaudanjo解決方案之上。由於我使用的是叉勺,我添加此內spec_helper.rbSpork.each_run塊,但你可能塊之前添加到任何其他每個/本。

# Define random prefix to prevent indexes from clashing
Tire::Model::Search.index_prefix "#{Rails.application.class.parent_name.downcase}_#{Rails.env.to_s.downcase}_#{rand(1000000)}"

# In order to know what all of the models are, we need to load all of them
Dir["#{Rails.root}/app/models/**/*.rb"].each do |model|
  load model
end

# Refresh Elastic Search indexes
# NOTE: relies on all app/models/**/*.rb to be loaded
models = ActiveRecord::Base.subclasses.collect { |type| type.name }.sort
models.each do |klass|
  # make sure that the current model is using tire
  if klass.respond_to? :tire
    # delete the index for the current model
    klass.tire.index.delete

    # the mapping definition must get executed again. for that, we reload the model class.
    load File.expand_path("../../app/models/#{klass.name.downcase}.rb", __FILE__)
  end
end

它基本上為每個測試用例定義了它自己的唯一前綴,因此索引中沒有。其他解決方案都遇到了一個問題,即使在刪除索引之後,Elastic Search也不會刷新索引(即使在運行之後Model.index.refresh),這就是隨機前綴存在的原因。

它還會加載每個模型並檢查它是否響應,tire以便我們不再需要維護spec_helper.rb在其他區域和其他區域響應輪胎的所有模型的列表

由於此方法在使用後不會“刪除”索引,因此您必須定期手動刪除它。雖然我不認為這是一個很大的問題,但您可以使用以下命令刪除:

curl -XDELETE 'http://localhost:9200/YOURRAILSNAMEHERE_test_*/'

要找到什麼YOURRAILSNAMEHERE,運行rails console和運行Rails.application.class.parent_name.downcase輸出將是您項目的名稱。