From Rails to Erlyweb - Part I

Updated July 20 2007: new params.erl which uses dict to store params and converts to proper type(integer/float/string)

It's time to migrate our project from Rails to Erlyweb (It cost me one month to write an Erlang IDE before this happens :-)). I'll blog some tips of the procedure, focus on the differences between Rails and erlyweb.

1.How to handle params

Rails:
page = params.fetch(:p, 1).to_i
size = params.fetch(:s, @@RECORDS_PER_PAGE).to_i
Erlyweb:
-module(mymodel_controller)..
-define(RECORDS_PER_PAGE, 9).

list(A) ->
    P = params:from_yaws_arg(A)
    Page = params:get("p", P, 1), %% return integer
    Size = params:get("s", P, ?RECORDS_PER_PAGE),
    ....

You can also

Id = params:get("id", P, integer) %% return integer()
Id = params:get("id", P) %% return string()
%% Or, pass a fun to return the converted result
Id = params:get("id", P, fun string:to_integer/1) 
To get the above code working, I wrote a params.erl and placed under folder: apps\myapp\lib.
-module(params).

-export([
         from_yaws_arg/1,
         from_list/1,
         get_page_opts/1,
         get_page_extras/1,
   get/2,
   get/3,
         get/4,
         convert/2,
         put/3,
         join/1
        ]).

%% @doc Convert yaws Arg#arg.querydata into a {key,value} stored in a dynamic hash.
from_yaws_arg(Arg) ->
    Params = yaws_api:parse_query(Arg),
    dict:from_list(Params).

from_list(PropsList) ->
    dict:from_list(PropsList).

get_page_opts(Dict) ->
    [{page, get("p", Dict, 1)},
     {page_size, get("s", Dict, ?DEFAULT_PAGESIZE)}].

get_page_extras(Dict) ->
    Page = get("p", Dict, 1),
    Size = get("s", Dict, ?DEFAULT_PAGESIZE),
    Offset = (Page - 1) * Size, 
    [{limit, Offset, Size}].

get(Key, Dict) ->
    get(Key, Dict, undefined).

%% @spec get(Key::term(), Arg:yawsArg(), Default::term() -> string()
get(Key, Dict, Fun)  when is_function(Fun) ->
    case get(Key, Dict, undefined) of
        undefined -> undefined;
        Value     -> Fun(Value)
    end;
get(Key, Dict, Type) when is_atom(Type) andalso Type /= undefined -> 
    get(Key, Dict, undefined, Type);
get(Key, Dict, Default) ->
    case dict:find(Key, Dict) of
        {ok, Value} when is_list(Default)    -> convert(Value, string); 
        {ok, Value} when is_integer(Default) -> convert(Value, integer);
        {ok, Value} when is_float(Default)   -> convert(Value, float);
        {ok, Value} -> Value;
        error       -> Default
    end.
    
get(Key, Dict, Default, Type) ->
    Value = get(Key, Dict, Default),
    convert(Value, Type).

convert(Value, _Type) when Value == undefined -> undefined;
convert(Value,  Type) ->
    try
        case Type of
            integer when is_list(Value)    -> list_to_integer(Value);
            integer when is_integer(Value) -> Value;
            integer when is_float(Value)   -> erlang:round(Value);
            float   when is_list(Value)    -> list_to_float(Value);
            float   when is_integer(Value) -> Value * 1.0;
            float   when is_float(Value)   -> Value;
            string  when is_list(Value)    -> Value;
            string  when is_integer(Value) -> integer_to_list(Value);
            string  when is_float(Value)   -> float_to_list(Value);
            number  when is_list(Value) andalso Value /= "" andalso Value /= "NaN" ->
                case string:chr(Value, $.) > 0 of
                    true  -> list_to_float(Value);
                    false -> list_to_integer(Value)
                end;
            number  when is_integer(Value) -> Value;
            number  when is_float(Value)   -> Value
        end
    catch error:_ -> 
        undefined
    end.

put(Key, Value, Dict) ->
    dict:store(Key, Value, Dict).

join(Params) ->
    ParamPairedStrs =
        dict:fold(
            fun (Key, Value, Acc) ->
                    [Key ++ "=" ++ yaws_api:url_encode(Value)|Acc]
            end, [], Params),
    %% Join params string with "&": ["a=a1", "b=b1"] => "a=a1&b=b1"
    join("&", ParamPairedStrs).

%% @spec join(string(), list(string())) -> string()
join(String, List) -> join(String, List, []).
join(_String, [], Joined) -> Joined;
join(String, [H|[]], Joined) -> join(String, [], Joined ++ H);
join(String, [H|T],  Joined) -> join(String, T,  Joined ++ H ++ String).
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值