I'm building an Rails app with a survey form which passes the responses as JSON format. Creation of answers works fine, however not quite sure how to approach the update.
Survey has got answers in the survey_answers table. Survey_answer has user_id, survey_id, question_id and response fields. That means however that every survey_answer is a separate record.
I can access the specific response through something like
SurveyAnswer.where(user_id: 1, survey_id: 1, question_id: 1).response
and update through that but then again, not sure how to handle it with JSON.
What do you think it's the best way to approach it?
Send the json to the Survey endpoint. Add accepts_nested_attributes for survey_answers to survey. Structure the json so that it looks like so:
{
survey: {
name: '',
survey_answer_attributes: [
{
...
},
{
...
}
]
{
}
White list the nested params. Basically RTFM.
Related
Despite much research and trial and error, I unfortunately do not yet have an elegant solution for the following use case:
A user has several posts, which is correctly implemented as a one-to-many relationship. I want to load the user with all his posts, but not all attributes of the posts, only certain ones.
Approach 1: Find
await this.usersRepository.find({relations: ['posts']});
Here I can't define a corresponding select restriction anywhere.
Approach 2: QueryBuilder
await this.usersRepository.createQueryBuilder('user')
.leftJoinAndSelect('user.posts', 'posts').select('posts.title').getMany();
Here I define the restriction supposedly, but the select seems to refer only to user.
Am I missing something? Or is there no intended solution for my use case?
I would be very grateful for help, thanks guys!
TypeORM version 0.2.22
I was able to get the appropriate results you're expecting. You don't have to use getRawMany if you don't want to, and need the nested objects like I do from getMany and getManyAndCount in the way my schema is built up.
That being said, if you have the correct OneToMany relation setup in your entity
#OneToMany(type => Post, post => post.user)
posts: Post
Then you should be able to hit
const userResults: any = await getRepository(entities.User)
.createQueryBuilder('user')
.leftJoinAndSelect('user.posts', 'posts')
.select([
'posts.name',
'user.id'
])
.getMany()
Which results in
userResults User {
id: 3,
posts: [ Post { name: 'asdfasdfasdf' }, Post { name: 'asdf' } ] }
Hope this helps, and/or you figured this out.
Use getRawMany() instead of getMany() if you want to select some fields
try
await this.usersRepository.createQueryBuilder('user')
.leftJoinAndSelect('user.posts', 'posts')
.select('posts.title')
.getRawMany();
For more info :
https://github.com/typeorm/typeorm/blob/master/docs/select-query-builder.md#getting-values-using-querybuilder
[EDIT] I am using the React and Rails differently and not using the react-rails gem...
Ok so i have my api written in Rails and it is formatted like this:
data: {
comments: [
{
comment: 'Lorem Ipsum',
user_id: 1
},
{
comment: 'dolor sit',
user_id: 2
},
{
comment: 'amet',
user_id: 3
}
]
}
now, in my react view, i want to have somewhat like, <%= User.find_by_id(params[:id]).name %>. What am I thinking is just to add posted_by attribute to table and add it as a key in api, having the string value of the user_id already set up with the controller(rails approach) and another one is to write another request(react approach) that will just fetch the name but i think its too much. What is the better approach?
In my opinion, it really depends on the numbers. You don't want to make, say, 15 requests if you have 15 comments on that page. My general proposing would be to keep this as close to JSON API as possible. However, if you want to stick to your current case, I would have two datasets:
1.Comments - which would be something like you have already
2.Users - Array of users, with all required fields (like name).
So that you would do only two requests initially.
Ok so this might be late. I just added a relationship between user and comments and added posted_by: Comment.user.name in the json response
I'm converting an email template from Rails to Mandrill, the content for which requires a fair amount of data, some of which is nested through several associations.
Therefore, I'd like to pass objects via Mandrill's global_merge_vars, such as the (simplified) following:
[{ 'name'=>'order', 'content'=> #order.to_json(include:
{ user: { only: :first_name } },
methods: [:method1,
:method2,
:method3,
:method4])
}]
Which passes through to the mandrill template under the order variable similar to the following:
{"id":11,"number":"xxxx","item_total":"112.0"...
"user":{"first_name":"Steve"},"method1":"£0.00","method2":"£112.00",
"method3":"£112.00","method4":"£0.00"}
The problem is, I can't access anything within order (using Handlebars), i.e. {{order.id}}, {{order['id']}} etc. wont work.
It's not an option to break out data into a large number of variables, as some elements are collections and their associations.
I believe the problem occurs as everything is stringified when the variables are compiled for Mandrill -- therefore breaking the JSON object -- with the following a snippet of what is sent across:
"global_merge_vars"=>[{"name"=>"order", "content"=>"{\"id\":11,
\"number\":\"xxxx\",\"item_total\":\"112.0\"...
I can't seem to find any documentation / suggestions for dealing with this, so am wondering whether this it's possible to pass data of this nature, and, if so, how to correctly pass it to be able to access the objects in the Mandrill template. Any advice greatly appreciated!
Steve.
try this:
[{ 'name'=>'order', 'content'=> JSON.parse(#order.to_json(include:
{ user: { only: :first_name } },
methods: [:method1,
:method2,
:method3,
:method4]))
}]
I am using Net::HTTP to get data out of a JSON API, and want to save the response given by the API in my database.
An example response is:
{
"id": 1234,
"applicationname": "test12347127834",
"publish_key": "79123798d7981728397dddasetr7912",
"streamname": "xxnamexx",
"ingest": "rtmp://master.cdn.com/SSDEL1"
}
I want to save the id, applicationname, publishkey and streamname.
I have absolutely no clue how that could work. I would highly appreciate if someone could give me a hint, tips or examples.
There are two approaches I see. One is simply to save your JSON as text. If you won't be doing a lot of post-processing of this attribute, that might do the job.
The second approach is to use :serialize on the column and Rails 3 will magically handle the back-and-forth interpolation for you. You'll be able to do
some_object.response.id
To do that simple do:
class YourClass
serialize :response
I am currently in the process of making my first iphone app with a friend of mine. He is coding the front end while I am doing the back end in Rails. The thing is now that he is trying to send necessary attributes to me with a post request but without the use of a nested hash, which means that that all attributes will be directly put in params and not in a "subhash". So more specifically what I want to do is be able to retrieve all these attributes with perhaps some params method. I know that params by default contains other info which for me is not relevant such as params[:controller] etc.. I have named all attributes the same as the model attributes so I think it should be possible to pass them along easily, at least this was possible in php so I kind of hope that Rails has an easy way to do it as well.
So for example instead of using User.new(params[:user]) in the controller I have the user attributes not in the nested hash params[:user] but in params directly, so how can I get all of them at once? and put them inside User.new()?
I found the solution to my problem. I had missed to add the attr_accessible to my model which was what initially returned the error when I tried to run code like: User.new(params) having been passed multiple attributes with the post request.
The solution was very simple, maybe too simple, but since this is my first real application in Rails I feel that it might be helpful for other newbies with similar problems.
If you would like to just pass a more limited version of params to new, you should be able to do something like the following:
params = { item1: 'value1', item2: 'value2', item3: 'value3' }
params.delete(:item2)
params # will now be {:item1=>"value1", :item3=>"value3"}
Also see this for an explanation of using except that you mention in your comment. An example of except is something like:
params.except(:ssn, :controller, :action, :middle_name)
You can fetch the available attributes from a newly created object with attribute_names method. So in this special example:
u = User.create
u.attributes = params.reject { |key,value| !u.attribute_names.include?(key)
u.save