【问题标题】:Issue implementing model问题实施模式
【发布时间】:2011-12-19 15:25:40
【问题描述】:

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

这是模型:

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!

【问题讨论】:

  • 请提供params[:substring]样品
  • 例如,url 的结尾是 ?substring="la",这显然与 Alabama、Alaska 和一堆其他字符串匹配,但我仍然收到“不匹配”
  • 请注意,您永远不应该在迁移中使用模型。在未来的某个时候,您甚至可能没有状态模型,此时此迁移将无效并且不会运行。使用execute 直接插入数据会更好,虽然更烦人。

标签: ruby-on-rails model migration


【解决方案1】:

我认为您遇到的问题是由于误用了 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+。

【讨论】:

    猜你喜欢
    • 2014-07-27
    • 1970-01-01
    • 2020-09-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-16
    相关资源
    最近更新 更多