Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Data wont render solution #212

Closed
shireen-bean opened this issue Aug 1, 2016 · 8 comments
Closed

Data wont render solution #212

shireen-bean opened this issue Aug 1, 2016 · 8 comments

Comments

@shireen-bean
Copy link

@shireen-bean shireen-bean commented Aug 1, 2016

Page would not render data for profile.

Routes were set up correctly but this was the model:

export default DS.Model.extend({
  given_name: DS.attr('string'),
  user_id: DS.belongsTo('user'),
  level: DS.attr('integer'),
  favorites: DS.hasMany('favorite'),
  schedules: DS.hasMany('schedule'),
});

Errors Thrown:

vendor.js:42222 TypeError: Cannot read property 'some' of undefined
message: "No model was found for 'favorite'", name: "Error"…}
message: "Assertion Failed: Unable to find transform for 'integer'", name: "Error"…}

Solution Part 1:
You can't insert into a model a property DS.hasMany if that property does not yet have a model defined somewhere in your ember client.

Solution Part 2;
DS.attr('number')
Not integer.

@shireen-bean
Copy link
Author

@shireen-bean shireen-bean commented Aug 1, 2016

^ See solution above.
Thanks @payne-chris-r

@shireen-bean
Copy link
Author

@shireen-bean shireen-bean commented Aug 2, 2016

So I created the model, and it still throws the error that the model doesnt exist.

This is my profile model:

export default DS.Model.extend({
  given_name: DS.attr('string'),
  user_id: DS.belongsTo('user'),
  level: DS.attr('number'),
  favorites: DS.hasMany('favorites'),
  // schedules: DS.hasMany('schedule'),
});

And this is my favorite model:

export default DS.Model.extend({
  profile_id: DS.belongsTo('profile'),
  recipe_id: DS.belongsTo('recipe')
});

The error is:
message: "No model was found for 'favorite'

I've tried playing around with the pluralizations: making a model for "favorites", saying profile has many "favorite" singular. Am I just messing up the pluralizations or am I linking these relationships incorrectly?

@shireen-bean shireen-bean reopened this Aug 2, 2016
@shireen-bean
Copy link
Author

@shireen-bean shireen-bean commented Aug 2, 2016

Trying to follow this guid as directed from older closed solutions but what exactly are the inverses>

https://guides.emberjs.com/v2.5.0/models/relationships/

When I follow the guide, I get an errror that say it cant find my inverses

@berziiii
Copy link

@berziiii berziiii commented Aug 2, 2016

If favorites is a join table, you may need to have

profile_id: DS.belongsTo('profile', {
inverse: 'favorites'}),
recipe_id:DS.belongsTo('recipe, {
inverse: 'favorites'})

Also, check to make sure in your API you have those Inversei set in your favorites model.

Let me know if his changes anything.

@berziiii
Copy link

@berziiii berziiii commented Aug 2, 2016

Then through this favorites join, you should be able to call profiles from recipes and the other way around without having to reference the join table.

@shireen-bean
Copy link
Author

@shireen-bean shireen-bean commented Aug 2, 2016

^I did that last night and got:
ReferenceError: favorites is not defined(…)
That's when I had a favorite model defined.

So i made a "favorites" (plural) model and got the same error.

I tried every combination of singular in my profile model, and even when I make both of them "favorite" (singular) it still says "favorites undefined" in the plural.

I have the inverses labeled in my backend as:

class Favorite < ActiveRecord::Base
  belongs_to :profile, foreign_key: :profile_id, inverse_of: :favorites, dependent: :destroy
end

and

class Profile < ActiveRecord::Base
  belongs_to :user, foreign_key: :user_id
  has_many :favorites, inverse_of: :profile
  has_many :schedules, inverse_of: :profile
end

@jrhorn424
Copy link

@jrhorn424 jrhorn424 commented Aug 2, 2016

For serializing relationships out of the backend, you'll want to look at listr-api serializers.

You don't want to use _id on key names on the front end. Our adapters and serializers take care of that for you in Ember. Last time I did use _id I'm pretty sure I had issues loading child model instances from parents.

export default DS.Model.extend({
  given_name: DS.attr('string'),
-  user_id: DS.belongsTo('user'),
+  user: DS.belongsTo('user'),
  level: DS.attr('number'),
  favorites: DS.hasMany('favorites'),
  // schedules: DS.hasMany('schedule'),
});
export default DS.Model.extend({
-  profile_id: DS.belongsTo('profile'),
+  profile: DS.belongsTo('profile'),
-  recipe_id: DS.belongsTo('recipe')
+  recipe_id: DS.belongsTo('recipe'),
});
@shireen-bean
Copy link
Author

@shireen-bean shireen-bean commented Aug 2, 2016

SOLUTION:

I got favorites to work and this solution is going to walk through how to do it for a similar join table that I have called "schedules" which also joins a profile to a recipe.

Moral of the issue: Ember works like an angel if you give it what it wants from the backend, and you run into a bit of trouble if you give it more than it wants. (Hence the importance of the pluck(:id)

BACKEND:

PROFILE MODEL:

class Profile < ActiveRecord::Base
  belongs_to :user, foreign_key: :user_id
  has_many :favorites
  has_many :recipes, through: :favorites

  has_many :schedules
  has_many :recipes, through: :schedules

end

Schedules Model:

class Schedule < ActiveRecord::Base
  belongs_to :profile, foreign_key: :profile_id, inverse_of: :schedules, dependent: :destroy
  belongs_to :recipe, foreign_key: :recipe_id, inverse_of: :schedules, dependent: :destroy
end

Recipes Model:

class Recipe < ActiveRecord::Base
  has_many :tags, inverse_of: :recipe
  has_many :ratings, inverse_of: :recipe
  has_many :profiles, through: :favorites
  has_many :favorites

  has_many :profiles, through: :schedules
  has_many :schedules
end

Profile Serializer:

class ProfileSerializer < ActiveModel::Serializer
  attributes :id, :given_name, :level, :user_id, :favorites, :schedules, :recipes

  def favorites
    object.favorites.pluck(:id)
  end

  def schedules
    object.schedules.pluck(:id)
  end

  def recipes
    object.recipes.pluck(:id)
  end

end

Schedule Serializer:

class ScheduleSerializer < ActiveModel::Serializer
  attributes :id, :eat_on, :profile_id, :recipe_id, :recipe, :profile

  def recipe
    object.recipe.id
  end

  def profile
    object.profile.id
  end
end

Recipe Serializer:

class RecipeSerializer < ActiveModel::Serializer
  attributes :id, :title, :directions, :time, :image, :ingredients, :level, :tags, :ratings, :favorites, :profiles

def favorites
  object.favorites.pluck(:id)
end

def schedules
  object.schedules.pluck(:id)
end

def profiles
  object.profiles.pluck(:id)
end


end

FRONT END:

Schedule Model:

import DS from 'ember-data';
import { belongsTo } from 'ember-data/relationships';

export default DS.Model.extend({
  profile: DS.belongsTo('profile', { inverse: 'schedules' }),
  recipe: DS.belongsTo('recipe', { inverse: 'schedules' }),
});

[the routes for schedule are the normal findAll for plural and findRecord for singular]

Profile Model:

import DS from 'ember-data';
import { hasMany } from 'ember-data/relationships';
import { belongsTo } from 'ember-data/relationships';

export default DS.Model.extend({
  given_name: DS.attr('string'),
  user: DS.belongsTo('user'),
  level: DS.attr('number'),
  recipes: DS.hasMany('recipe')
});

Recipe Model:

import DS from 'ember-data';
import { hasMany } from 'ember-data/relationships';

export default DS.Model.extend({
  title: DS.attr('string'),
  directions: DS.attr(),
  time: DS.attr('number'),
  image: DS.attr('string'),
  ingredients: DS.attr(),
  profiles: DS.hasMany('profile')
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
3 participants
You can’t perform that action at this time.