2015-05-09 35 views
0
$ rails -v 
Rails 4.2.1 
$ ruby -v 
ruby 2.2.2p95 (2015-04-13 revision 50295) [x86_64-linux] 

我一直在使用rails大約一個月,現在正試圖做一個簡單的json api。我大部分工作正常,但在返回基於關係的自定義數據時遇到了問題。Rails路線返回某些標準

寶石文件(僅供參考):

source 'https://rubygems.org' 

gem 'rails', '4.2.1' 
gem 'sass-rails', '~> 5.0' 
gem 'uglifier', '>= 1.3.0' 
gem 'coffee-rails', '~> 4.1.0' 
gem 'jquery-rails' 
gem 'turbolinks' 
gem 'jbuilder', '~> 2.0' 
gem 'sdoc', '~> 0.4.0', group: :docgi 
gem 'mongoid' 
gem 'rspec-its', '~> 1.2.0' 
gem 'unicorn', '~> 4.9.0' 
gem 'kaminari' # adds pagination to ActiveModels 
gem 'devise', '~> 3.4.1' 
gem 'simple_token_authentication', '~> 1.9.1' 
gem 'cancancan' 

group :development do 
    gem 'quiet_assets', '~> 1.1.0' 
end 

group :development, :test do 
    gem 'rspec-rails', '~> 3.2.1' 
    gem 'byebug' 
    gem 'web-console', '~> 2.0' 
    gem 'spring' 
    gem 'factory_girl_rails', '~> 4.5.0' 
end 
group :test do 
    gem 'capybara', '~> 2.4.4' 
    gem 'capybara-email', '~> 2.4.0' 
    gem 'shoulda-matchers', '~> 2.8.0' 
end 

正如你所創業板文件中看到,我使用蒙戈通過mongoid。然後,我有我的用戶模型:

class User 
    include Mongoid::Document 
    include Mongoid::Timestamps 
    has_many :posts 

    validates :email, presence: true, 
      uniqueness: true, 
      format: { 
       with: /\A[A-Za-z0-9._%+-][email protected][A-Za-z0-9\.-]+\.[A-Za-z]+\Z/ 
      } 
    validates :username, presence: true, uniqueness: true 
    validates :telephone, presence: true 
    validates :name, presence: true 
    validates :gender, presence: true 
    validates :dob, presence: true 
    validates :photo_url, presence: true 
    validates :password, presence: true 
    # Include default devise modules. Others available are: 
    # :confirmable, :lockable, :timeoutable and :omniauthable 
    devise :database_authenticatable, :registerable, :trackable, :validatable 
    ## Token Authenticatable 
    acts_as_token_authenticatable 
    field :authentication_token 

    ## Profile 
    field :name,    type: String, default: "" 
    field :gender,    type: Boolean, default: 0 
    field :dob,    type: Date 
    field :telephone,   type: String 
    field :username,   type: String 
    field :photo_url,   type: String 
    field :last_action,  type: Time 
    ## Database authenticatable 
    field :email,    type: String, default: "" 
    field :encrypted_password, type: String, default: "" 

    ## Trackable 
    field :sign_in_count,  type: Integer, default: 0 
    field :current_sign_in_at, type: Time 
    field :last_sign_in_at, type: Time 
    field :current_sign_in_ip, type: String 
    field :last_sign_in_ip, type: String 

    ## Indexes 
    index({ email: 1, username: 1 }) 
    index({ gender: 1, dob: 1, telephone: 1, posts: -1}) 

end 

而且我們已經得到了相關這裏是has_many :posts

現在我知道我可以返回所有的人,像這樣的關係:

user = current_user 
    render json: user.as_json(include: :posts), status: :created, location: @user 

這可以工作,它會將帖子添加到結果集中。我不確定該怎麼做,這是這裏的問題,是如何根據標準返回特定的結果。

例如,我有一個路線,我想抓住用戶,但只想抓住他們的最後一個帖子。另一條路線是我想抓住用戶和他們的所有帖子,但是在過去24小時的時間內,帖子排序爲最新到最舊,我不太清楚如何正確地做到這一點。

一個例子結果集我在尋找實現:

{ 
_id: "5548245663686f2a58030000", 
authentication_token: "KG6qksJaUzKwU7aZxt94", 
created_at: "2015-05-05T02:00:54.467Z", 
dob: null, 
email: "[email protected]", 
gender: false, 
last_action: null, 
name: "", 
photo_url: null, 
telephone: null, 
updated_at: "2015-05-05T02:00:54.467Z", 
username: null, 
posts: [ ... ] 
} 

回答

1

屬於要搶奪用戶和他們的最後一個職位的路線的動作,你可以這樣做:

last_post = current_user.posts.last 
render json: last_post.to_json 

您的其他途徑(如你想抓住從降序排序過去24小時內的用戶和他們所有的職位),你可以試試這個:

posts = current_user.posts.where('created_at >= ?', 1.day.ago).order created_at: :desc 
render json: posts.to_json 

更新

你可以看看ActiveModal::Serializer儘量完美地解決您的問題。你可以爲實例創建一個UserSerializer看起來如下:

class UserSerializer < ActiveModel::Serializer 
    attributes :id, :name, :last_post, :posts_from_last_day # and whatever else you want to be included 

    has_many :posts 

    def last_post 
    object.posts.last 
    end 

    def posts_from_last_day 
    object.posts.where('created_at >= ?', 1.day.ago).order created_at: :desc 
    end 
end 

在你的控制,你會比有類似:

render json: current_user, serializer: UserSerializer 

作爲一個額外的,你甚至可以創建一個scope或方法你Post模型,從串行刪除條件:

class Post 
    ... 

    def from_last_day 
    where('created_at >= ?', 1.day.ago).order created_at: :desc 
    end 
end 

比你可以改變posts_from_last_day方法在UserSerializer到:

def posts_from_last_day 
    object.posts.from_last_day 
end 

更新,第二部分

如果你不想在同一個請求,你可以創建兩個獨立的串行last_postposts_from_last_day信息:

class UserSerializer < ActiveModel::Serializer 
    attributes :id, :name, :last_post # and whatever else you want to be included 

    has_many :posts 

    def last_post 
    object.posts.last 
    end 
end 

在您要檢索以上數據的操作中:

render json: current_user, serializer: UserSerializer 

而且你可以創建以下串行其他動作:

class UserLastDaySerializer < ActiveModel::Serializer 
    attributes :id, :name, :posts_from_last_day # and whatever else you want to be included 

    has_many :posts 


    def posts_from_last_day 
    object.posts.from_last_day 
    end 
end 

這將是所謂的喜歡:

render json: current_user, serializer: UserLastDaySerializer 
+0

這樣做將返回用戶的數據呢?因爲這是api,所以在調用路由時,我需要能夠返回用戶信息,除了帖子或最後一篇文章。 這確實給了我一點幫助,不過謝謝你。我用一個示例結果集更新了問題,我們期待實現的目標。最終,我需要弄清楚如何將方法鏈接在一起,因爲我將包括朋友等等,並且帖子也有數據加入。 – Justin

+0

@Justin我已經更新了我的答案。這應該讓你朝正確的方向發展。這有幫助嗎? – newmediafreak

+0

這是有道理的,讓我走上正軌,去做我需要的東西。感謝您對這個問題的幫助和支持,我的'noobness'。但是,這確實會讓您想到這個問題:創建序列化程序時,它看起來好像自動調用'from_last_day'和屬性中的任何其他方法。那麼,我是否正確,我需要爲每個要創建的唯一結果集創建序列化程序? – Justin