Rails将参数传递给页面并根据它们调用不同的方法

时间:2011-11-23 10:40:48

标签: ruby-on-rails

我继续提出来自PHP的新手问题,下面可能有多个问题,感谢您的耐心等待。

我正在努力实现的目标:

我有一个名为search.html.erb的模板(视图),我希望根据用户输入调用不同的方法,特别是获取前一页中链接传递的变量。因此,如果用户单击“逗号”链接,则会传递类似

的内容
search?type=commas

(我已经替换了类型的操作,因为我理解在Rails中为在Controller内声明的方法保留'action')。路径文件包含:

  match ':controller/:action/:type/'

这应该允许我做“http:// localhost:3000 / actors / search / commas作为传递'逗号'类型的方式?

然后搜索页面将从Actors Model中调用showCommas方法:

def self.showCommas
    @commas = self.where("actor LIKE ?", "%,%,%")
end

如果他们点击“急性”,它就会通过

search?type=acute

该页面将调用Actors模型中的急性方法。

最后,我还希望他们能够传递搜索词,搜索页面将使用.find_by_sql对该词进行SQL查询。

这在PHP中实现是微不足道的,我只是使用

if ($_GET[action] == 'commas') { ...

但是如何在Rails中做到这一点?我遇到的问题:

如果我在Actor控制器中为搜索词创建一个方法:

def search(term)    
    Actor.find_by_sql([sql query here with '%#{term}%']) 
end

Rails会抱怨控制器中的方法有太多参数。所以我把所有的方法都移到了模型上(猜测这是正确的方法吗?)

将其放入我的search.html.erb页面:

if type.nil?
    criteria = "No type specified"
elsif type == 'commas' 
    criteria = type
    @actors = Actor.showCommas
end

给我一​​个关于未定义的类型变量的错误:未定义的局部变量或方法`type'

所以我做了很多东西,但是和Rails一样,来自PHP,很难围绕Rails的做事方式。我理解使用与您的操作同名的视图的主要哲学,Rails会调用它,但我不想为每个查询(或其他小东西)构建一个页面,我需要做。此外,我读过的书似乎没有详细说明这一点,所以,再次感谢你的帮助和放纵,在一篇文章中提出多个问题。

2 个答案:

答案 0 :(得分:0)

不要在模型中执行此操作,请在控制器中执行此操作。您自动获取GET参数(就像在PHP中一样)。这是在参数哈希。例如,你可以做一个案例:

def search
  case params[:type]
  when 'commas'
    search_with_commas
  when 'acute'
    search_with_acute
  ...
  else
    default_search
  end
end

private
  def search_with_commas
     ...
  end

  ...

当然,如果您只需要修改查询,您只需在何时获取查询并在一个操作中处理所有内容。

答案 1 :(得分:0)

很难完全回答这个问题,因为缺少一些信息,但希望这会引导你朝着正确的方向前进。 你的search?type=commas网址将路由到actor控制器,在那里看起来你有一个搜索方法。可以在params散列(params [:type])中访问type =逗号。

在rails中最好的做法就是尽可能多地将逻辑移到模型中,所以从php开始,在你的控制器中做这样的事情会很自然:

def search  
    if params[:type] 
        if params[:type] == "commas"
            ... search logic
        elsif
            ... other search logic
        end 
    end
end

在Rails中,使用命名约定的控制器方法看起来更像是这样;

def search 
    @actors = Actor.search(params[:type])
end

请注意params[:type]访问您的类型url参数。您编写它的方式是您将类型作为控制器方法参数,这是不正确的,因为控制器方法没有参数。

模型可能看起来像这样;

def self.search(type)
    case type
    when "commas"
      Actor.where(:type => "commas")
    when "whatever"
      Actor.where(:type => "whatever")
    else
      Actor.all
    end
end

您的搜索方法显然会有很大不同,但这只是如何将params从url传递到模型的示例。