简体   繁体   English

Rails + Ember.js + Devise自由记者应用程序-数据范围

[英]Rails + Ember.js + Devise freelance journalist app - data scoping

Apologies, I have been in ember.js-land for so long, I'm fumbling Rails + active_model_serializers JSON api basics. 抱歉,我已经在ember.js领域呆了很长时间了,我在弄乱Rails + active_model_serializers JSON api基础知识。

So let's say I'm a freelance journalist and am building an app where a writer can publish Articles to different Company-specific sites through a single user account. 假设我是一名自由撰稿人,并且正在构建一个应用程序,作家可以通过一个用户帐户将文章发布到公司特定的不同站点。

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

I am using Rails 3+, Devise, Active_Model_Serializers, Ember-Data and Ember.js. 我正在使用Rails 3 +,Devise,Active_Model_Serializers,Ember-Data和Ember.js。

I want to set up a flow where the user comes to the site, logs in (very easy using devise) and is redirected to a rails page where he can select which Company's dashboard he wants to go to (by just clicking on a link). 我想建立一个流程,使用户可以访问该网站,登录(非常容易使用devise),然后重定向到Rails页面,在该页面中,他可以选择他想去的公司仪表板(只需单击链接)。 。

Now comes the tricky part. 现在是棘手的部分。 When he clicks on a specific company's link, he should be directed to a Rails view that contains an ember app whose serialization scope is set to the current_company_membership or current_company and not just the current_user. 当他单击特定公司的链接时,应将其定向到包含Ember应用程序的Rails视图,该应用程序的序列化范围设置为current_company_membership或current_company,而不仅仅是current_user。

How do I create a rails or active_model_serializers method that scopes data to just the current_company as dictated by current_company_membership, and then passes along this data to the ember app? 如何创建rails或active_model_serializers方法,以将数据范围限定为current_company_membership指示的current_company,然后将这些数据传递到ember应用程序?


Also, as a bonus, I need the name and email address of the current_user - how do I pass this information along to the ember app as well? 另外,作为奖励,我需要current_user的名称和电子邮件地址-如何将这些信息也传递给ember应用程序? I have seen this dude's article, but have not been able to get it working when trying to scope data through just company_membership and not current_user. 我看过这家伙的文章,但是当尝试仅通过company_membership而不是current_user来限定数据范围时,却无法使它正常工作。

Any help would be awesome! 任何帮助都是极好的! I'll add more detail and code if need be, but I have a feeling I'm forgetting something pretty simple here. 如果需要的话,我将添加更多细节和代码,但是我觉得我忘记了一些非常简单的内容。

Update: Way to access current_user and current_company rails methods in ember app described at bottom of answer and the github demo app has also been updated. 更新:答案底部描述了在ember应用程序中访问current_user和current_company rails方法的方法,并且github演示应用程序也已更新。


If I understand correctly what you're trying to do, below is one way to get the job done quickly. 如果我正确理解您要做什么,以下是一种快速完成工作的方法。 If anyone has a better answer, please edit my question. 如果有人有更好的答案,请编辑我的问题。 I have put up on github an ember + rails + devise demo app that combines the answer to this question and my last ember.js stackoverflow question to show that everything is working as it should be. 我在github上放置了一个ember + rails + devise 演示应用程序 ,该应用程序结合了该问题的答案和我的上一个ember.js stackoverflow问题,以表明一切正常。 Below I use the model Post instead of Article, but it's basically the same concept. 在下面,我使用模型Post而不是Article,但是基本上是相同的概念。

1) In the Rails Companies view, on specific company link_to click, you should pass the company variable to a rails controller action that's passed onward to an application helper method to set a devise session variable for current_company. 1)在Rails公司视图中,单击特定的公司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
...

The set_current_company method will set the current_company variable session-wide and redirect the user to the assets/index.html.erb rails view that contains your ember application. set_current_company方法将在整个会话范围内设置current_company变量,并将用户重定向到包含您的余烬应用程序的asset / index.html.erb rails视图。

2) You now need to scope your rails api data for Posts (and Comments, Company_Memberships) for current_company that you want to use in your json api/ember models, like so: 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) Then you should serialize the data through AMS to the ember app in a normal way: 3)然后,您应该以常规方式通过AMS将数据序列化到ember应用程序:

class PostSerializer < ActiveModel::Serializer
  attributes :id, :title, :body, :company_id, :user_id
  has_many :comments
end

4) Then on to the ember model. 4)然后到灰烬模型。

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

5) Ember Controllers, Views and templates should behave as expected. 5)Ember控制器,视图和模板的行为应符合预期。 Check out the demo app to see super basic implementations. 查看演示应用程序以查看超级基本实现。


In order to gain access to current_user and current_company, use active_model_serializers meta data serialization and then this guy's temporary solution to map your serializer so that it grabs the meta data and sets it to a global variable in your ember app. 为了获得对current_user和current_company的访问权,请使用active_model_serializers元数据序列化 ,然后使用此人的临时解决方案来映射您的序列化程序,以便它获取元数据并将其设置为ember应用程序中的全局变量。 This may not be best practices, but for now, it gets the job done. 这可能不是最佳做法,但是到目前为止,它已经完成了工作。

1) First, set your store.js grab the meta data from your json and set it to a global variable in your serializer: 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) Second, in your rails company_memberships_controller.rb render the meta data: 2)其次,在您的Rails中,company_memberships_controller.rb呈现元数据:

render json: @company_memberships, :meta => {:current_user => current_user, :current_company => current_company}

3) Finally, call any current_user or current_company attribute straight from your templates: 3)最后,直接从模板中调用任何current_user或current_company属性:

Logged in with: {{App.metaData.current_user.email}}
<br>
Current Company: {{App.metaData.current_company.name}}

Simply override the methods in the serializer. 只需重写序列化器中的方法即可。

def custom_association
  # scope is the current user
  CustomObjects.ownedBy(scope)
end

I'm not sure if I understand your problem completely, but: 我不确定我是否完全了解您的问题,但是:

You can set the serialization scope in your controller class definition (or on the ApplicationController base class): 您可以在控制器类定义中(或在ApplicationController基类上)设置序列化范围:

serialization_scope :current_company

You can also pass a scope to the serializer when you instantiate it. 您还可以在实例化范围时将范围传递给串行器。 So to return the JSON for record , you'd do this, in your controller method: 因此,要返回record的JSON,可以在控制器方法中执行以下操作:

record.active_model_serializer.new(record, scope: current_company).as_json

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM