2013-03-12 83 views
0

我有三张桌子; Area,MovieMovieArea。在rails中,我希望能够根据area_id字段Movie查询MovieArea。然后我想使用Movie中的字段返回复合json对象,并用MovieArea中的值替换相同名称的字段。如何从这三个模型创建复合JSON对象?

我有以下数据库结构:

enter image description here

及以下车型:

class Movie < ActiveRecord::Base 
    attr_accessible :title, :synopsis, :grossing, :director, :year, :facts 
    has_many :movie_areas, :class_name => 'MovieArea' 
end 

class Area < ActiveRecord::Base 
    attr_accessible :name 
    has_many :movie_areas, :class_name => 'MovieArea' 
end 

class MovieArea < ActiveRecord::Base 
    attr_accessible :movie_id, :area_id, :synopsis, :facts 

    belongs_to :area, :class_name => 'Area', :foreign_key => :area_id 
    belongs_to :movie, :class_name => 'Movie', :foreign_key => :movie_id 
end 

最后,我一直在试图使用模型的方法和改变JSON创建该对象响应。在模型中加入:

def grossing 
    self.movie.grossing 
end 
def year 
    self.movie.year 
end 
def title 
    self.movie.title 
end 

等。而在控制器:

@results = MovieArea.where(:area_id => @area.id) 

最后,在视图:

<%= @results.to_json(:methods => [:grossing, :year, :title]).html_safe -%> 

这工作得很好,我得到JSON的类型我想要的对象:

[ 
    { 
     "id":1, 
     "area_id":1, 
     "movie_id":1, 
     "synopsis":"Area relevant movie synopsis", 
     "facts":"Area relevant movie facts", 
     "grossing":"$9001M", 
     "year":"1999", 
     "title":"Movie title", 
    }, 
    ..... 
] 

所以问题是:有没有更好的方法来做到这一点?例如,我是否可以从模型中输出所有内容,并调用如MovieArea.where(:area_id => @area.id).some_function_to_respond?或者我可以将逻辑移动到控制器,因此在视图中它只需调用@results.to_json()

谢谢!

+1

你看过jbuilder吗? https://github.com/rails/jbuilder – jvnill 2013-03-12 10:19:33

+0

[RABL](https://github.com/nesquena/rabl)适合生成JSON或XML – shweta 2013-03-12 10:43:58

回答

0

有一个非常新的RailsCasts集涵盖了你想要做的事情。看看它here

0

我结束了使用RABL - 感谢您的建议shweta。我通过将以下内容添加到我的Gemfile并运行bundle install来安装它。

gem 'rabl' 
gem 'oj' 

我然后创建以下Rabl的模板movie_areas.json.rablviews/rabl文件夹:

object @movie 
attributes :id, :synopsis, :facts 
glue :movie do 
    attributes :title, :grossing, :director, :year 
end 

以上代码从movie_area表取idsynopsisfacts然后在titlegrossing增加,来自父母moviedirectoryear

要呈现出来的JSON直接在视图中,我需要在Backbone.js的使用,我呼吁:

<%= Rabl.render(@results, 'rabl/movie_areas').html_safe -%> 

@results是我的问题和rabl/movie_areas定义的变量ActiveRecord的查询指movie_areas.json.rabl模板。

以便输出来自控制器直接一个API,我用:

def movies 
    @area = Area.find_by_slug(params[:slug]) 
    @results = MovieArea.where(:area_id => @area.id) 
    render :inline => Rabl::Renderer.json(@results, 'rabl/movie_areas') 
end 

希望这将帮助别人的未来!

相关问题