问题实施模型

时间:2011-12-19 15:25:40

标签: ruby-on-rails model migration

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

以下是模型:

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!

1 个答案:

答案 0 :(得分:0)

我认为您遇到的问题是由于select方法的误用造成的。 ActiveRecord :: Base实现用于选择特定列。您正在将块传递给不需要的方法,因此将其忽略。最终结果是什么。

Ruby中有几种约定会使这种不当行为更加明显,更容易修复。例如,如果根据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 +。