New to Ruby on Rails 4.0 and I am having some trouble getting my JSON to add the data from my joined table. I am using AngularJS on the front end, and I can't seem to find a good example on here to help me out.
In short, I have a Invite with a User ID. I have a User with a User ID. Knowing the Invite ID, I want to get the name of the User that corresponds to that invite.
Invite 1: UserID: 10
Invite 2: UserID: 11
Invite 3: UserID: 12
UserID: 10 Name: Owen
UserID: 11 Name Greg
Controller - Invites
# GET /invites/1
# GET /invites/1.json
def show
#invite = Invite.includes(:user).find(params[:id]).to_json(include: :user)
end
Model - Invite
class Invite < ActiveRecord::Base
belongs_to :user
has_one :meal
has_one :event
has_one :registry
end
Model - User
class User < ActiveRecord::Base
has_one :invite
end
However I only get this whenever I check the /invites/1.
{"id":1,"created_at":"2013-12-06T20:14:39.001Z","updated_at":"2013-12-06T20:58:15.597Z","event_id":7,"meal_id":8,"registry_id":0,"rsvp":false,"user_id":9}
Any help here is much appreciated!
Your show should be:
def show
#invite = Invite.includes(:user).find(params[:id])
respond_to do |format|
format.json { render :json => #invite.to_json(include: :user) }
end
end
I recommend you to use JBuilder http://rubygems.org/gems/jbuilder . You can use #invite.to_json, but JBuilder gives you much more control on the output.
Related
I am using Stream Rails to build an app with a feed. The user has some page which other users can follow. For that I created a page feed group. Here is my Post model -
class Post < ApplicationRecord
belongs_to :page
belongs_to :author, class_name: "User"
has_one :post_item, inverse_of: :post
accepts_nested_attributes_for :post_item
include StreamRails::Activity
as_activity
def activity_object
self.post_item
end
def activity_actor
self.author
end
end
However, the posts go to user's feed. How can I also make it go to the page feed group? I looked through the github code, and I think I have to override activity_owner_feed? But I also want the author to have a list of all the posts they have created. So the posts need to be in the user feed too.
Here is the corresponding code from my controller -
# this method creates the post
# This puts the post in user feed
# I also want to add the post to page feed
def create
#post = current_user.posts.build post_params
#post.save
render json: { success: true }
end
# show all posts of a user
def show
feed = StreamRails.feed_manager.get_user_feed(current_user.id)
enricher = StreamRails::Enrich.new
results = feed.get()['results']
#activities = enricher.enrich_activities(results)
render json: { activity: #activities }
end
Corresponding routes -
post 'post/create'
post 'post/show'
You need to override activity_notify and return an array of feeds to be notified.
It translates to to target in the generated activity.
I have this model, called products, that has an id, user_id and product_name.
I have a simple form_for to pass to my product_controller the product_name param. In this same controller, I have access to the current_user, which I have to pass in order to create a new Product.
The problem is that the user_id always has to be the current user logged in, so I can't allow the user to send me this param in my form_for, thus I can't permit it as well.
What I'm doing right now is to create a new hash with the user_id param, and merge the params that comes from the form.
products_controller.rb:
def create
product_user_id_param = { "user_id": current_user.id.to_s }
#product = Product.new(product_user_id_param.merge(params[:product_name]))
...
end
Is there a more convenient or Rails way to do this?
You can create you product with you current_user reference, this is the more convenient way in my opinion:
current_user.produtcs.create(name: params[:product_name])
But, to above code works, you have to construct you relations correctly, like the following:
class User < ActiveRecord::Base
has_many :products
end
class Product < ActiveRecord::Base
belogs_to :user
end
Now, you can do it!
You can read more about it, in https://guides.rubyonrails.org/v3.2/association_basics.html, the docs recommeds this way!
Solution #1
Product has user_id which means product belongs_to :user and user has_many :products
Hence it can be written as
current_user.products.new(product_name: params[:product_name])
Solution#2
Set current_user explicitly
#product = Product.new(product_name: params[:product_name])
#product.user_id = current_user.id
##product.user = current_user
#product.save
Why is this undefined? Does it have something to do with the #current_user?
I'm trying to create tasks for my challenges. And the created task should get /achievements. However, I get a GET 500 error.
This is the error I get:
NoMethodError at /achievements
==============================
> undefined method `achievements' for #<User:0x00000105140dd8>
app/controllers/achievements_controller.rb, line 5
--------------------------------------------------
``` ruby
1 class AchievementsController < ApplicationController
2
3
4 def index
> 5 #achievements = #current_user.achievements
6 render :json => #achievements
7 end
8
9 def new 10 #achievement = Achievement.new
This is my code in my controller
class AchievementsController < ApplicationController
def index
#achievements = #current_user.achievements
render :json => #achievements
end
def new
#achievement = Achievement.new
render :json => #achievement
end
#create a new achievment and add it to the current user
#check then set the acheivments pub challenge id to the current pub challenge
def create
#achievement = Achievement.new achievement_params
#achievement.user = #current_user.id
#achievement.pub_challenge = params[:id]
if #achievement.save
# render :json => #achievement #{ status: 'ok'}
else
render :json => {:errors => #achievement.errors}
end
end
def show
#achievement = Achievement.find params[:id]
render :json => #achievement
end
def destroy
#achievement = Achievement.find params[:id]
#achievement.destroy
end
private
def achievement_params
params.require(:achievement).permit(:pub_challenges)
end
end
You are missing the has_many :achievements relation in your User model.
You'll need to create the ActiveRecord associations you require:
#app/models/user.rb
class User < ActiveRecord::Base
has_many :achievements
end
#app/models/achievement.rb
class Achievement < ActiveRecord::Base
belongs_to :user
end
This will give you the ability to call the achievements method on any User objects you have.
Error
The error you have is described as such:
undefined method `achievements' for #<User:0x00000105140dd8>
This basically means that you're trying to call an undefined method on a User object. Might sound simple, but really, most people don't understand it.
To explain properly, you have to remember that Rails, by virtue of being built on Ruby is object orientated. This means that everything you do in Rails should be structured around objects - which are defined in your Models:
This means that each time you call an object, you're actually above to invoke a series of "methods" which will give you the ability to either manipulate the object itself, or any of the associated functionality it has.
The problem you have is that your User object doesn't have the achievements method. Whilst you could simply do the following to fix the issue, because it's Rails, you'll need to populate the record with associative data:
#app/models/user.rb
class User < ActiveRecord::Base
has_many :achievements #-> what you need
def achievements
#this will also fix the error you see, although it's fundamentally incorrect
end
end
Something that helped me with this type of error was that the database table was missing the relevant column. Adding the required column to the database fixed the issue.
I want to retrieve an entire user object via a get request. Currently, on of my methods looks like this:
def user
#user = User.find(current_user.id)
render :json => #user
end
This returns the following json:
"{\"annonymous_token\":null,\"email\":\"john1#doe.com\",\"name\":\"john1#doe.com\"}"
My user object / schema has a many-to-many relationship with another model called pictures.
has_many :picturization
has_many :pictures, :through => :picturization
How can I modify my code such that returning the user also returns the pictures the user has. If helpful, I am using devise for user authentication.
Thanks!
You can use .as_json and pass params as I show here: https://stackoverflow.com/a/11336145/308701
so you could do:
def user
#user = User.find(current_user.id)
render :json => #user.as_json(:include => :pictures)
end
Have you tried #user.to_json?
Hello I am a Rails Noob so I apologize if this is elementary. I'm creating a Twitter-like application and working on a 'reply' button that will automatically place a variable (the username of the tweet's author) into the tweet form at the top of the page. This is what I have now:
def reply
#tweet = Tweet.find(params[:id])
#message = User.find_by_user_id(params[#tweet])
end
I know that I'll have to change my routes but that's what I'm hung up on.
Any help would be greatly appreciated, thanks. I'm, again, a noob.
Your first line of code finds Tweet object. Then you put that tweet object into params hash as a key (this is the error). And AFAIK - you'd want to look into javascript that sets value for hidden field.
This should work for you:
def reply
#tweet = Tweet.find(params[:id])
#message = #tweet.user.username
end
It assumes that the Tweet model has an association called user and that your User model has an attribute username:
class Tweet < ActiveRecord::Base
belongs_to :user
...
end
class User < ActiveRecord::Base
has_many :tweets
...
end
And this would probably match the current behaviour of twitter a bit better:
def reply
#tweet = Tweet.find(params[:id])
#message = "#" + #tweet.user.username + " "
end