2011-12-19 89 views
0

至少,我认为这就是问题的原因...... 我试图创建一个页面,通过查询字符串发送子字符串,并且显示与子字符串匹配的给定数组的成员在页面上。我知道逻辑在我的模型作品中,但显然有些东西是不正确的,因为当我发送匹配数组的几个成员的子字符串时,它会返回“无匹配”。我很确定问题出在模型或迁移的某个地方。问题实施模型

这里的模型:

class State < ActiveRecord::Base 
def State.filter(matching_string) 

    matcher = Regexp.new(matching_string, Regexp::IGNORECASE) 
    @new_array = [] 
    State.select{|x| if matcher =~ x then @new_array << x end} 
    return @new_array 

end 
end 

这里的迁移:

class CreateStates < ActiveRecord::Migration 


def self.up 

    list_of_states = ["Alabama", "Alaska", "Arizona", "Arkansas", "California", 
    "Colorado", "Connecticut", "Delaware", "Florida", "Georgia", 
    "Hawaii", "Idaho", "Illinois", "Indiana", "Iowa", 
    "Kansas", "Kentucky", "Louisiana", "Maine", "Maryland", 
    "Massachusetts", "Michigan", "Minnesota", "Mississippi", "Missouri", 
    "Montana", "Nebraska", "Nevada", "New Hampshire", "New Jersey", 
    "New Mexico", "New York", "North Carolina", "North Dakota", "Ohio", 
    "Oklahoma", "Oregon", "Pennsylvania", "Rhode Island", "South Carolina", 
    "South Dakota", "Tennessee", "Texas", "Utah", "Vermont", 
    "Virginia", "Washington", "West Virginia", "Wisconsin", "Wyoming"] 


    create_table :states do |t| 
     t.string :name 
     t.timestamps 
    end 
    State.reset_column_information 
    for x in list_of_states 
      State.create(:name => x) 

    end 
    State.all.collect {|x| x.name} 
    end 



    def self.down 
    drop_table :states 
    end 
end 

而这里的控制器:

class StatesController < ApplicationController 
def filter 
    @states = State.filter(params[:substring]) 
    @entered_string = params[:substring] 
end end 

TIA!

+0

请提供'params [:substring]'sample – Bohdan 2011-12-19 15:28:17

+0

例如,url的结尾是?substring =“la”,显然与阿拉巴马州,阿拉斯加州和其他一些字符串相匹配,但我是仍然收到“不匹配” – user1104967 2011-12-19 15:52:06

+0

作为说明,您不应该在迁移中使用模型。在将来的某个时候,你甚至可能还没有一个状态模型,此时该迁移将无效并且不会运行。使用'execute'直接插入数据虽然更麻烦,但好得多。 – tadman 2011-12-19 16:27:46

回答

0

我认为你遇到的问题是由于错误地使用了select方法。 ActiveRecord :: Base实现用于选择特定的列。你将一个块传递给一个不需要的方法,这样它就会被忽略。最终的结果是什么都没有。

Ruby中有几个约定会使这种不正当行为更明显,更易于修复。举例来说,这是多么如果按照红宝石约定完成的方法将被写入:

class State < ActiveRecord::Base 
    def self.filter(matching_string) 
    pattern = Regexp.new(matching_string, Regexp::IGNORECASE) 

    State.select{ |state| state.name.match(pattern) } 
    end 
end 

你会发现,这种方法的结果总是nil,这样的东西是不对的。你真正想要的更多是这样的:

class State < ActiveRecord::Base 
    def self.filter(matching_string) 
    pattern = Regexp.new(matching_string, Regexp::IGNORECASE) 

    @states ||= State.all 
    @states.select{ |state| state.name.match(pattern) } 
    end 
end 

这假定你不在应用程序重新启动之间添加和删除状态。如果处理仅限美国的数据,这是一个相当安全的假设,特别是因为您的数据通过迁移加载并且看起来不是用户可编辑的。

使用LIKE运营商用户也可以简单地搜索数据库:

class State < ActiveRecord::Base 
    def self.filter(matching_string) 
    State.where('name LIKE ?', "%#{matching_string}%") 
    end 
end 

第一种方法适用于国家的小型列表更好,后者为大名单。在这种情况下,“大”意味着1000+。