I'm trying to assign random user_id's to products that are generated from the seeds database. Everything is generating for me as I want it except for the user_id which is rendering nil. I'm trying to get a better understanding of how the belongs_to interaction works - any help here would be awesome!
10.times do |n|
name = Faker::Name.name
job = Faker::Company.name
User.create!(name: name,
job: job )
end
10.times do |n|
users = User.all
name = "Turkey"
price = Random.rand(42-10) + 10
user_id = users[1..10]
Product.create!(name: name,
price: price,
user_id: user_id)
end
Thanks in advance for the help!
Edit ** Thanks for the help everyone. This is what I ended up changing the code to.
users = User.order(:created_at).take(6)
10.times do |n|
name = "Turkey"
price = Random.rand(42-10) + 10
users.each { |user| user.products.create!(name: name, price: price)}
end
I'm not 100% what you're asking in terms of assigning a random user id to the product. From your comment on #tadman answer it seems you just want a product to belong to each one of the users. Why not just do something like this:
10.times do |n|
name = Faker::Name.name
job = Faker::Company.name
User.create!(name: name, job: job)
end
User.all.each do |user|
name = "Turkey"
price = Random.rand(42-10) + 10
user.products.create!(name: name, price: price)
end
Assuming your User model has many products and a product belongs to a User that should get your desired outcome.
user.products will automatically assign the user.id to the user_id field to the product record when sending build or create
You probably mean this:
user_id = users.last.id
Or possibly:
user_id = users.shuffle.last.id
I'm not sure what your range notation 1..10 is intending. Arrays are 0-indexed.
User id will automatically get generated for each new user in sequential order. There is no need to have the "user_id" field there.
Like Mukul215 said the ID will be generated automatically in sequential order. It is BAD practice to hard code ID's in the seed.
Related
I need to get some data from ActiveRecord, I have following two tables Department and users I have issue that I am getting one hash in which user is giving me user_ids and emails, now I want to create hash container users, departments and emails in specific format. I have tried a lot map/select but still could not figure out any simple way.
class User < ApplicationRecord
belongs_to :department
end
And Department
class Department < ApplicationRecord
has_many :users
end
I am getting following values from user
sample_params = [{ user_id: 1, email: 'example1#example.com' },
{ user_id: 5, email: 'example5#example.com' },
{ user_id: 13, email: 'example13#example.com'}]
Now I have retrieve departments from database and other data and join in one huge hash so I can add it to my class. I can get all my users by following command
users = User.where(id: sample_params.map{ |m| m[:user_id] })
I will get whole ActiveRecord objects with all users if I run following command I am getting all user_id and project_id
users.map { |u| {user_id: u.id, department_id: u.department_id } }
I will get this
[{:user_id=>1, :department_id=>3},
{:user_id=>5, :department_id=>3},
{:user_id=>13, :department_id=>2}]
but I want to create following hash, Is there any simple way to do it directly using query or in other few lines, I can try using Iteration but that would be very long and complicated. As I also need to merge emails in it and add one project instead of same projects multiple ids.
[
{department_id: 1, users: [{user_id: 1, email: 'example1#example.com'},
{user_id: 5, email: 'example5#example.com'}]},
{department_id: 2, users: [{ user_id: 13, email: 'example13#example.com']
I am using here sample data the real data is very very large include hundreds of users and many departments.
I don't think you can do it in one go! let us run throgh and try how can we solve it. First instead of using map in your params let us try another alternate for it. Remove following line
users = User.where(id: sample_params.map{ |m| m[:user_id] })
user following line
User.where(id: sample_params.pluck(:user_id)).pluck(:department_id, :id).grou
p_by(&:first)
This will bring you result in each users id with department grouping in one query
{3=>[[3, 1], [3, 5]], 2=>[[2, 13]]}
Now we are getting department_id and user_id so we will run map on them to get first array with department_id and user_id in a group with following command
data =
User
.where(id: sample_params.pluck(:user_id))
.pluck(:department_id, :id)
.group_by(&:first).map do |department_id, users|
{ department_id: department_id,
users: users.map { |_, id| id } }
end
This will give you hash with department and users
[{:department_id=>3, :users=>[1, 5]}, {:department_id=>2, :users=>[13]}]
Now you have hash of department and users. so let us work on this this is second phase where I will use select to get email from your params and merge it to your data.
result = []
data.each do |department|
department_users = []
department[:users].each do |user|
emails = sample_params.select { |user| user[:user_id] == 1 }[0][:email];
department_users << { id: user, emails: emails }
end; result << {department_id: department[:department_id], users: department_users}
end
Now if you do puts result[0] you will get following hash as you wanted.
{:department_id=>3, :users=>[{:id=>1, :emails=>"example1#example.com"}, {:id=>5, :emails=>"example1#example.com"}]}, {:department_id=>2, :users=>[{:id=>13, :emails=>"example1#example.com"}]}
This will solve issue, I understand there are two operation but there is no double sql queries in single it is working and you are also replacing your emails. I hope it solve you issue, any one can make it simpler would be appreciated.
I want to pull every single student first name and last name from my job's database; so that I can keep updating my local database with new students. The issue is that the students' first names and last names are in different rows; therefore, when I try to save these students, I also get two different rows.
I have tried creating a student with Student.new(student_parameters) and then setting up two variables (one for the first name and the and other one for the last name) every time this information becomes available as the program rolls over every single piece of information.
After that, I have tried saving the student and then updating that same student; but it creates another row when I update it.
This is what I have as of now:
NewOcOrderOption.where("name = 'Student First Name' OR name = 'Student Last Name'").each do |key|
#binding.pry
#st = Student.new(student_params)
#st.id = key.order_id
#st.first_name = key.value if key.name == "Student First Name"
#st.save!
stu = Student.find(#st.id)
#st.last_name = key.value if key.name == "Student Last Name"
stu.update_attribute(:last_name, #st.last_name) if #st.last_name != nil
##st.save!
end
If I am not explaining myself well, I deeply apologize. I have been tackling this for 5 hours now. Thank you.
Also, this is all taking place at my student's controller.
Edit:
The original database looks like this
This is how I want it to look like:
id first_name last_name
4074 Cristian Polanco
4075 Raul Person
This is the output:
id first_name last_name
4074 Cristian NULL
4074 NULL Polanco
4075 Raul NULL
4075 NULL Person
You can use group_by on NewOcOrderOption records.
It will return an hash with order_id as key and all the options (for this id) as value:
NewOcOrderOption.all.group_by(&:order_id).each do |id, options|
student = Student.new
options.each do |option|
case option.name
when 'Student First Name' then student.firstname = option.value
when 'Student Last Name' then student.lastname = option.value
end
end
student.id = id
student.save!
end
However, note that id is attr_protected and you should add another attribute to the Student model to store the order_id instead of override the id primary key (you can check this post for more explaination)
I have a User model
class User < ActiveRecord::Base
has_many :skills
has_one :profile
end
Profile table has two columns named, age & experience
Now, I've a search form where the parameters are passed are:
params[:skill_ids] = [273,122,233]
params[:age] = "23"
params[:experience] = "2"
I've to search through all the users where user's skills meet any of the params[:skill_ids] and also from the user's profile, their age and experience.
Do I have to go through a loop like:
users = []
User.all.each do |user|
if (user.skills.collect{|s| s.id} & params[:skill_ids] ) > 0
// skip other parts
users << user
end
end
or, any of you have any better solution?
Because your skills belong to exactly one user, you could first fetch all users belonging to the skill ids provided and filter them by the other criteria:
matching_users = User.includes(:skills, :profile)
.where(["skills.id in (?) AND profile.age = ? AND profile.experience = ?",
params[:skill_ids],
params[:age].to_i,
params[:experience].to_i]
)
Try this:
#users = User.includes(:skills).where(["skills.id in (?)", params[:skill_ids]]).all
In a Rails app I'm setting up nested routes
resource Country do
resource State
resource City
resource User
resource Post
end
I now want to display users that have posted within a country at ../country/1/users
In the User controller I have:
def index
#user = User.includes(:posts, :city, :state, :country)
#user = #users.where("states.country_id = ?", params[:country_id]) if params[:country_id]
#active_users = #users.where('posts_count > ?', 0).ranked_scope
end
I'm, getting:
PG::Error: ERROR: column reference "posts_count" is ambiguous
LINE 1: ...untry_id" WHERE (states.country_id = '1') AND (posts_co...
I'm not sure if this is because:
There is a posts_count column on User, City, State, Country models and the query does not know which on to use. If so, what is the correct syntax to specify the table?
I'm stringing together two where clauses incorrectly.
Something else....?
I'd appreciate any suggestions or ideas.
Try:
#active_users = #users.where('users.posts_count > ?', 0).ranked_scope
OK, I eventually got to the bottom of this. The following query was incorrect
#users = #users.where("states.country_id = ?", params[:country_id]) if params[:country_id]
Post belongs to User, and Post has one Country through State. Without a direct relationship in one direction between USer and Country, I modified the query to
#users = #users.where(id: Country.find(params[:country_id]).users.uniq if params[:country_id]
(and double checked all my model relationships were properly configured).
Works!
The error message was not very helpful in tracking this down though!
I have 3 tables: Student, Subject and Score.
Every student can add 3 Subjects (Physics, Mathematics and Chemistry) marks.
The combination of (student_id + subject_id) is added to Score table. I.e., capturing that sudent '1' has added 'Mathematics' marks with the actual score (say 0-100 range)
student id : subjectid Score
1 Mathematics 95
The Add page of Score has a "subject" drop down. which is displayed from "subject" table.
When the student wants to add the 2nd subject marks, in the add page, he should not be displayed the previoys added subject in the drop down.
Can anyone tell me how to do this?
Yes, you can do it in the following way (Rails 3.0):
class Subject
scope :not_enrolled_in, lambda{ |user| where("NOT EXISTS(SELECT id FROM scores WHERE user_id = ? AND subject_id = subjects.id)", user.id) }
end
Or this way in Rails 2.x:
class Subject
named_scope :not_enrolled_in, lambda{ |user| { :conditions => ["NOT EXISTS(SELECT id FROM scores WHERE user_id = ? AND subject_id = subjects.id)", user.id] } }
end
You can then get a list of subjects the current user has not enrolled in this way:
Subject.not_enrolled_in(current_user).all
You can then use this list in your select HTML code.