Sylar
Sylar

Reputation: 12072

How Does ReactJS Handles Rails Active Record Associations

I'm iterating over a user's post items. I can lists the items but not their profile based on my relationship:

Post Model:

belongs_to :user

Profile Model:

belongs_to :user

User Model:

has_many :posts
has_one :profile

PostsController:

class PostsController < ApplicationController
  respond_to :json

  before_action :set_post, only: [:show, :edit, :update, :destroy]
  before_action :only_current_user, except:[:show, :interest]

  # GET /posts
  # GET /posts.json
  def index
    @user = User.friendly.find( params[:user_id] )
  end
  [...]
end

Index page controller:

class PagesController < ApplicationController

    respond_to :json

    def index
        @users = User.all
        @posts = Post.all.order("created_at DESC")
    end
   [...]
end

Without JS, I get the values with:

<% @posts.each do |s| %>
 <%= s.user.profile.business_name %>
 <%= s.post_type %>
 <%= s.<all others> %>
<% end %>

Now with React, I can use the react-rails gem for this:

var Posts = React.createClass({

  render: function() {

    var createItem = (p) => (

    <div className="row">
      {p.post_type}
      {p.foobar}
      {p.user.name} //this does not work
    </div>

    );

    return (
      <div className="panel">
        {this.props.posts.map(createItem)}
      </div>
    );

  }
});

Index.html.erb:

<%= react_component('Posts', { posts: @posts } %>

I thought I had the answer but this just spits out all the users when I only want the user with associated post:

<%= react_component('Posts', { posts: @posts,
                               users: @users } %>

Then I'd add the props in the js but that's not what I want.

There seem to be a clue in my console that I'm trying to figure out:

"Warning: Each child in an array or iterator should have a unique "key" prop. Check the render method of Posts.

Upvotes: 8

Views: 2544

Answers (1)

nbermudezs
nbermudezs

Reputation: 2844

I don't think the warning has anything to do with the issue but just to get rid of it you can add the key prop in the React component like this:

var Posts = React.createClass({

  render: function() {

    var createItem = (p) => (

    <div className="row" key={p.id}>
      {p.post_type}
      {p.foobar}
      {p.user.name} //this does not work
    </div>

    );

    return (
      <div className="panel">
        {this.props.posts.map(createItem)}
      </div>
    );

  }
});

As for the real issue, please try changing the assignment of @posts to something like @posts = Post.all.includes(:user).as_json(include: { user: { only: [:name] } })

My guess is that you are just querying the posts. By default as_json (the method called when you return json data) does not include associations, therefore you won't get anything on the react side.

Upvotes: 17

Related Questions