创建自定义 rails 路由:“10”的未定义方法“+@”:字符串

Creating custom rails route: undefined method `+@' for "10":String

我正在制作自定义 rails 路线作为:

match '/setFavoriteRestaurant/:user_id/:restaurant_id/:campaignSetFav_id/:metro_id/:time_period', to: 'requests#setFavoriteRestaurant', via: 'get'

控制器动作:

def setFavoriteRestaurant
        setFavorite = "INSERT INTO androidchatterdatabase.users_favorite_restaurants(usersId,restaurantId,campaignIdSetFav,metroId,timePeriod,favoritedDt)
                       VALUES(" + params[:user_id].to_s + "," 
                                + params[:restaurant_id].to_s + "," 
                                + params[:campaignSetFav_id].to_s + ","
                                + params[:metro_id].to_s + ","
                                + params[:time_period].to_s + ",
                                NOW());"

        ActiveRecord::Base.connection.execute(setFavorite)
    end

然而在浏览器中测试时:http://localhost:3000/setFavoriteRestaurant/1/2/3/5/4

它 returns 一个奇怪的错误:undefined method +@' for "2":String

为什么其他方法、设置完全相同都可以 运行?

这与你如何分解台词有关。 Ruby 不知道 VALUES(" + 行和 + params[:restaurant_id] 是同一事物的一部分。这是因为 VALUES( + 行是完整的。将 + 移动到行尾,这样 Ruby 就会知道期望下一行是续行。

setFavorite = "INSERT INTO androidchatterdatabase.users_favorite_restaurants(usersId,restaurantId,campaignIdSetFav,metroId,timePeriod,favoritedDt)" + 
                      "VALUES(" + params[:user_id].to_s + "," +
                      params[:restaurant_id].to_s + "," +
                      params[:campaignSetFav_id].to_s + "," +
                      params[:metro_id].to_s + "," +
                      params[:time_period].to_s + ",NOW());"

另外,请注意我移动了一些其他的东西以避免换行和多余的空格。

我不确定你为什么喜欢这里的原始 SQL,但你应该考虑通过 Rails。似乎您正在接受 SQL 注射。至少,您可以在路由中设置一些约束以仅匹配整数。

Ruby 有几种引用多行字符串的方法:

1) 这里是 ruby 的 heredoc 语法:

def some_action

  setFavorite = <<-"END_OF_INSERT"
    INSERT INTO androidchatterdatabase.users_favorite_restaurants(
      usersId,
      restaurantId,
      campaignIdSetFav,
      metroId,
      timePeriod,
      favoritedDt
    )
    VALUES( 
      "#{params[:user_id]}",  
      "#{params[:restaurant_id]}",
      "#{params[:campaignSetFav_id]}",
      "#{params[:metro_id]}",
      "#{params[:time_period]}",
      NOW()
    );
  END_OF_INSERT

end

解释:

setFavorite = <<-"END_OF_INSERT"

-   =>  Terminator does not have to be at the start of the line.
""  =>  This is a double quoted string--do interpolation.

2) 这是 %Q{}:

  setFavorite = %Q{
    INSERT INTO androidchatterdatabase.users_favorite_restaurants(
      usersId,
      restaurantId,
      campaignIdSetFav,
      metroId,
      timePeriod,
      favoritedDt
    )
    VALUES( 
      "#{params[:user_id]}",  
      "#{params[:restaurant_id]}",
      "#{params[:campaignSetFav_id]}",
      "#{params[:metro_id]}",
      "#{params[:time_period]}",
      NOW()
    );
  }

但是,您的 SQL 语句仍然容易受到 sql 注入攻击。检查您的数据库适配器以了解如何进行参数替换。