2

抱歉,我在 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 应用程序?我看过这个花花公子的文章,但是在尝试仅通过 company_membership 而不是 current_user 来确定数据范围时,无法使其正常工作。

任何帮助都是极好的!如果需要,我会添加更多细节和代码,但我觉得我在这里忘记了一些非常简单的事情。

4

3 回答 3

3

更新:在答案底部描述的 ember 应用程序中访问 c​​urrent_user 和 current_company rails 方法的方法和github 演示应用程序也已更新。


如果我正确理解您要执行的操作,以下是快速完成工作的一种方法。如果有人有更好的答案,请编辑我的问题。我在github 上放了一个 ember + rails + devise 演示应用程序,它结合了这个问题的答案和我最后一个 ember.js stackoverflow 问题,以表明一切正常。下面我使用模型 Post 而不是 Article,但它的概念基本相同。

1) 在 Rails Companies 视图中,在特定公司 link_to click 上,您应该将 company 变量传递给 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 的 Posts(和 Comments、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) 然后到 ember 模型。

App.Post = DS.Model.extend({
  title: DS.attr('string'),
  body: DS.attr('string'),
  comments: DS.hasMany('App.Comment')
});

5) Ember 控制器、视图和模板应按预期运行。查看演示应用程序以查看超级基本实现。


为了获得对 current_user 和 current_company 的访问权限,请使用active_model_serializers 元数据序列化,然后使用这个人的临时解决方案来映射您的序列化程序,以便它获取元数据并将其设置为您的 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}}
于 2013-03-02T11:22:31.643 回答
2

只需覆盖序列化程序中的方法。

def custom_association
  # scope is the current user
  CustomObjects.ownedBy(scope)
end
于 2013-02-26T08:15:17.123 回答
0

我不确定我是否完全理解您的问题,但是:

您可以在控制器类定义(或 ApplicationController 基类)中设置序列化范围:

serialization_scope :current_company

您还可以在实例化时将范围传递给序列化程序。因此,要返回 JSON record,您可以在控制器方法中执行此操作:

record.active_model_serializer.new(record, scope: current_company).as_json
于 2013-02-26T14:53:33.277 回答