道歉,我已经在ember.js-land工作了这么久,我正在摸索Rails + active_model_serializers JSON api基础知识。
所以,假设我是一名自由撰稿人,正在建立一个应用程序,作者可以通过一个用户帐户将文章发布到不同的公司特定网站。
Rails Relationships
User has_many :company_memberships
User has_many :companies, :through => :company_memberships
Company has_many :company_memberships
Company_membership belongs_to :user
Company_membership belongs_to :company
Article belongs_to :company_membership
Article has_many :comments
Comment belongs_to :article
我正在使用Rails 3 +,Devise,Active_Model_Serializers,Ember-Data和Ember.js。
我想建立一个流程,用户访问该网站,登录(使用设计非常简单)并重定向到rails页面,在那里他可以选择他想去的公司的仪表板(只需点击一条链接)。
现在是棘手的部分。当他点击特定公司的链接时,他应该被定向到一个Rails视图,其中包含一个ember应用程序,其序列化范围设置为current_company_membership或current_company,而不仅仅是current_user。
如何创建rails或active_model_serializers方法,根据current_company_membership的规定将数据范围限定为current_company,然后将此数据传递给ember应用程序?
另外,作为奖励,我需要current_user的名称和电子邮件地址 - 如何将此信息传递给ember应用程序?我看过this dude's文章,但在尝试通过company_membership而不是current_user来调整数据范围时,却无法使其正常工作。
任何帮助都会很棒!如果需要,我会添加更多细节和代码,但我有一种感觉,我忘记了一些非常简单的事情。
答案 0 :(得分:3)
更新:在答案底部描述的ember app中访问current_user和current_company rails方法的方法,github demo app也已更新。
如果我理解你正在尝试做什么,下面是快速完成工作的一种方法。如果有人有更好的答案,请编辑我的问题。我已经提出了github an ember + rails + devise demo app,它结合了这个问题的答案和my last ember.js stackoverflow question,以表明一切正常运作。下面我使用模型Post而不是Article,但它基本上是相同的概念。
1)在Rails Companies视图中,在特定公司link_to上,您应该将公司变量传递给rails控制器操作,该操作将传递给应用程序帮助程序方法,以便为current_company设置设计会话变量。
<% @companies.each do |company| %>
<%= link_to 'Company Dashboard', set_current_company_company_path(:id => company) %>
<% end %>
class CompaniesController < ApplicationController
def set_current_company
session[:company_id] = params[:id]
redirect_to assets_path
end
...
end
class ApplicationController < ActionController::Base
...
helper_method :current_company
def current_company
@current_company ||= Company.find_by_id!(session[:company_id])
end
...
end
App::Application.routes.draw do
resources :companies do
member do
get :set_current_company
end
end
...
set_current_company方法将在会话范围内设置current_company变量,并将用户重定向到包含您的ember应用程序的assets / index.html.erb rails视图。
2)您现在需要为要在json api / ember模型中使用的current_company的帖子(和评论,Company_Memberships)设置rails api数据的范围,如下所示:
class PostsController < ApplicationController
def index
@posts = Post.where(company_id: current_company.id)
render json: @posts
end
def create
@post = Post.new(params[:post].merge :company_id => current_company.id)
respond_to do |format|
if @post.save
render json: @post, status: :created, location: @post
else
render json: @post.errors, status: :unprocessable_entity
end
end
end
3)然后你应该以正常方式通过AMS将数据序列化到ember应用程序:
class PostSerializer < ActiveModel::Serializer
attributes :id, :title, :body, :company_id, :user_id
has_many :comments
end
4)然后到了余烬模型。
App.Post = DS.Model.extend({
title: DS.attr('string'),
body: DS.attr('string'),
comments: DS.hasMany('App.Comment')
});
5)灰烬控制器,视图和模板应该按预期运行。查看demo app以查看超级基本实现。
要获得对current_user和current_company的访问权限,请使用active_model_serializers meta data serialization然后this guy's temporary solution映射序列化程序,以便抓取元数据并将其设置为您的ember应用中的全局变量。这可能不是最佳做法,但就目前而言,它可以完成工作。
1)首先,设置你的store.js从json中获取元数据并将其设置为序列化器中的全局变量:
App.CustomRESTSerializer = DS.RESTSerializer.extend({
extractMeta: function(loader, type, json) {
var meta;
meta = json[this.configOption(type, 'meta')];
if (!meta) { return; }
Ember.set('App.metaData', meta);
this._super(loader, type, json);
}
});
App.Store = DS.Store.extend({
revision: 11,
adapter: DS.RESTAdapter.create({
bulkCommit: false,
serializer: App.CustomRESTSerializer
}),
});
App.ready = function() {
App.CompanyMembership.find();
}
2)其次,在你的rails中,company_memberships_controller.rb呈现元数据:
render json: @company_memberships, :meta => {:current_user => current_user, :current_company => current_company}
3)最后,直接从模板调用任何current_user或current_company属性:
Logged in with: {{App.metaData.current_user.email}}
<br>
Current Company: {{App.metaData.current_company.name}}
答案 1 :(得分:2)
只需覆盖序列化程序中的方法。
def custom_association
# scope is the current user
CustomObjects.ownedBy(scope)
end
答案 2 :(得分:0)
我不确定我是否完全理解你的问题,但是:
您可以在控制器类定义(或ApplicationController基类)中设置序列化范围:
serialization_scope :current_company
您还可以在实例化范围时将范围传递给序列化程序。因此,要返回record
的JSON,您需要在控制器方法中执行此操作:
record.active_model_serializer.new(record, scope: current_company).as_json