我正在收集有关世界上所有国家/地区的公开数据,并且需要能够解析该JSON文件,以便为每个国家/地区提取相关内容并将其存储到我的数据库中。
我有点不清楚我应该编写逻辑来解析数据并保存数据库中每个国家/地区的每个相关部分 - 在模型或控制器中?我几乎把它放在我的控制器的根索引中,一旦用户访问就开始解析,但我只是觉得这违背了胖模型,瘦控制器的rails惯例。
非常感谢任何和所有帮助。谢谢!
答案 0 :(得分:2)
对于我自己来说,我的Rails工作已经演变成更多的MVCS类型方法。我尽可能保持控制器的瘦弱和轻盈(对我来说,他们只不过是#34;交通警察和#34;框架)。
我尝试同样保持我的模型轻松,其中添加的方法代表模型及其数据或其行为。例如,在具有名字和姓氏属性/字段的java.lang.object
模型中,我通常会添加一个名为User
的方法,该方法首先连接到最后一个。
如果程序要求不属于那些或类似的用例,我倾向于使用我存储在name
中的服务。
至少在我看来,经典的,做得很好的例子是搜索模型,我很少将其放在模型中。相反,我在控制器中接收搜索请求(当然),然后将params和任何其他相关细节发送到服务类并让它完成工作。
这是一个非常基本的搜索示例......非常基本:)!
/app/services
我有一个超级简单,但名称很gem that generates a service和一个rspec模板,以防你尝试使用服务方法。
如果有兴趣,请在" Rails服务"上进行网络搜索。并且有丰富的数据!
祝你好运!答案 1 :(得分:2)
你绝对正确的做法是将所有逻辑放在控制器中会违反瘦小的控制器。
一种方法是通过模型上的方法解析来自api的数据:
class Cat < ActiveRecord::Base
def self.create_from_kittypix_api(data, &block)
model = self.new(attrs_from_some_api(data))
yield(model, data) if block_given?
model
end
def self.attrs_from_kittypix_api(data)
{
foo: data[:bar]
}
end
end
这里的缺点是你的模型最终对外部API了解得太多,一次创建几个模型会导致对责任的混淆。
更新的方法是using services,它是普通的旧红宝石对象,它接受输入并完成给定的任务。
class KittypixImportService
def self.call(kitty_pix_id)
client = KittyPixClient.new
result = client.get_kitty(id: kitty_pix_id)
Cat.new(
foo: result['bar']
)
end
end