Take random ids, then store those random ids into the db - ruby-on-rails

so I'm working on a code snippet that essentially takes out 35 random ids from the table List.
What I would like to do to find the ids that got randomly generated, store them into a database called Status.
The purpose is to avoid duplication the next time I get a new 35 random ids from the List. So I never get the same random id twice.
Here's what I've tried, but been unsuccessful to get working.
#schedule = current_user.schedules.new
if #schedule.save
#user = User.find(params[:id])
Resque.enqueue(ScheduleTweets, #user.token)
#schedule.update_attribute(:trial, true)
flash[:notice] = "success"
redirect_to :back
else
flash[:alert] = "Try again."
redirect_to :back
end
and the worker:
def self.perform(user_token)
list = List.first(6)
#status = list.statuses.create
list.each do |list|
Status.create(list_id: "#{list}")
if list.avatar.present?
client.create_update(body: {text: "#{list.text}", profile_ids: profile_ids, media: { 'thumbnail' => 'http://png-1.findicons.com/files/icons/85/kids/128/thumbnail.png', 'photo' => 'http://png-1.findicons.com/files/icons/85/kids/128/thumbnail.png' } })
end
end
end
however the Status.create(list_id: #list) doesn't work.
Does anybody have any idea what is going on, and how I can make the list_ids get saved successfully to Status?
It's also associated:
list has many statuses, and status belongs to list

The following line of code is wrong:
Status.create(list_id: "#{list}") # WRONG
In your case the list variable is a List instance. And you're passing its string version to list_id which expects an integer.
Do this:
Status.create(list_id: list.id)
Or this:
list.statuses.create
I think the following will also work:
Status.create(list: list)

Related

How to enter a list of codes in the text field, through "," and get the same number of separate objects Rails

I am writing one project Ruby on Rails, and i'm stuck in one place.. I have a class Product, this class has_many: class Codes. Now, i enter the codes one at a time into the text box, and I get one object with one code.
I want to enter a list of codes in the text field, through "," and get the same number of separate objects.
I am getting this error -
TypeError in GiftCodesController#create
no implicit conversion of String into Integer
When I check with a debugger, I don't see any Integer
#code = Code.new(code_params)
if #code.code.include? ","
#array = #code.ode.split(",")
#array.each do |n|
#code.code = #array[n]
#code.save
end
flash[:success] = "CodeĀ“s added!"
redirect_to root_path
else
if #code.save
flash[:success] = "Code added!"
redirect_to root_path
else
flash[:danger] = "Error!"
end
end
The each method returns the VALUE of each array element, not the index.
So this is wrong...
#array.each do |n|
#code.code = #array[n]
#code.save
end
This would be correct...
So this is wrong...
#array.each do |n|
#code.code = n
#code.save
end
But even that would be wrong, as you want to create a new code for each array element, so...
#array.each do |n|
code = #product.codes.build
code.code = n
code.save
end
There are some edge cases you'll also need to address, like how to edit existing codes for a product, but hopefully this will start you off.

Import and Create Records from CSV

I'm trying create records in the Pairing table from a CSV file upload. The file given will be in this format
supervisor,student,project_title
Bob,Alice,Web Site
Bob,Charlie,Web Application
Issue is the Pairing table doesn't hold supervisor or student names but rather their IDs, so it would be necessary to search the User table for these given names and select their IDs then create the Pairing with these ids and the given project title.
The code below is giving me a too many redirects error and inserting a null record into the pairings table.
Pairing.rb
def self.import(file)
CSV.foreach(file.path, headers: true) do |row|
supervisorName = row[0]
studentName = row[1]
title = row [2]
supervisorID = User.select(:id).where(name: supervisorName)
studentID = User.select(:id).where(name: studentName)
pair = Pairing.new
pair.supervisor_id = supervisorID
pair.student_id = studentID
pair.project_title = title
pair.save
end
end
Pairings_controller.rb
def new
#pairing = Pairing.new
end
def create
#pairing = Pairing.new(pairing_params)
if #pairing.save
redirect_to pairings_path, :notice => "Pairing Successful!"
else
redirect_to pairings_path, :notice => "Pairing Failed!"
end
end
def import
Pairing.import(params[:file])
redirect_to pairings_path, :notice => "Pairs Imported"
end
The statement User.select(:id).where(name: supervisorName) won't return an integer value as you're expecting. Consider using User.find_by(name: supervisorName).id Instead.
As for too many redirects, make sure that the action matching your pairings_path doesn't redirect back to itself or other actions that may yield circular redirects.

Rails saving array with the duplicated elements

I'm populating an array with multiple elements (some of then are equals, thats what I want). My code is something like this:
def create
#order = Order.create()
#order.table = Table.find_by(:number => params['table'][0])
#products ||= []
#qtd = []
Product.all.each do |product|
params['order'].each_pair do |ordered|
if(product.id.to_s == ordered.first)
for i in 0..ordered.second[0].to_i
#order.products << product
#order.save
end
end
end
end
binding.pry #here the #order.products is the way I want to
if #order.save
flash[:success] = "Pedido criado com sucesso."
redirect_to tables_path
else
flash[:danger] = "Erro ao criar pedido."
render :new
end
end
But When I go to rails console and do Order.last.products he dosen't show me de duplicated elements like I saved on my controller. Whats happening?
Well in your case you should be sending order information from client to server like
"order"=>{"line_items_attributes"=>{"0"=>{"quantity"=>"4", "id"=>"127"}}}
Instead of repeating the product id in the list, your should implement a concept of line items in your system. Line Items are the objects representing items that are added to your shopping cart and instead of repeating the product_id you can use term quantity.
Now you can have separate model called LineItem. Order can have many LineItems. LineItem has many products.
For more info see What is a "order line"?
For current Implementation:
<< method does not allow duplicate entries. It filters out the duplicates. Its basically relates products with order since order can have multiple products via some_table. It cannot relate same product to the order twice.
My suggestion would be, create a string field(column) called products and add the serialized array of product ids.
order.products = [1, 1, 3, 4,4,4].to_s
while accessing you de-serialize.

Rails Activerecord: Update where conditions... else create

I need to check multiple columns of a table to see if I find a match. If I find a match I need to "updateattributes" of the matching record with all of my form params... Else I need to add a new record with all of my form params.
if #somethingtoupdate = Model.where("column1 = ? and column2 = ?", params[:something][:column1], params[:something][:column2])
if #somethingtoupdate = Model.update_attributes(params[:something])
redirect_to somewhere_path, :notice => "The existing record was updated"
else
render "myformlocation"
end
else
#added = Model.new(params[:something])
if #added.save
redirect_to somewhere_path, :notice => "The new record was created"
else
render "myformlocation"
end
end
Update
#somethingtoupdate = Model.where("this_id = ? and that_id = ?", params[:something][:this_id], params[:something][:that_id])
if ! #somethingtoupdate.empty?
if #somethingtoupdate.update_attributes(params[:something])
redirect_to some_path, :notice => "The existing record was updated"
else
render "myformlocation"
end
else
#added = Model.new(params[:something])
if #added.save
redirect_to some_path, :notice => "The new record was created"
else
render "myformlocation"
end
end
This is where I stand now thanks to #micahbf.
But, I am still getting an error on my "update_attributes" when there is a matching record.
Seems like this should work.... What am I missing or doing wrong?
This is because where does not return nil if it doesn't find anything, it returns an empty array, which is still truthy, so the block gets executed.
You can use empty? to check whether to run the block or not.
Note also that if it finds a match, the match will still be returned inside of an array (even if there was only one match). So you will have to do something like call first on the result to take the first returned model and update it.
So, the top might look like:
#somethingtoupdate = Model.where("column1 = ? and column2 = ?", params[:something][:column1], params[:something][:column2])
if ! #somethingtoupdate.empty?
if #somethingtoupdate.first.update_attributes(params[:something])
redirect_to some_path, :notice => "The existing record was updated"
else
render "myformlocation"
end
else
// do stuff if the query found no matches
end
I think here is short method to find record and if found then update record and if record not found then create it.
#somethingtoupdate = Model.where("column1 = ? and column2 = ?", params[:something][:column1], params[:something][:column2]).first_or_initialize
#somethingtoupdate.update_attributes(params[:something])
First of all, Model.update_attributes(params[:something]) is not working (at least in Rails 3.2.12). It should be #somethingtoupdate.update_attributes(params[:something]).
Also, there is an existing method for this kind of purpose: first_or_create.
#somethingtoupdate = Model.where("column1 = ? and column2 = ?", params[:something][:column1], params[:something][:column2]).first_or_create

assigning values to model

I'm kinda new to coding on rails. It would be great if you could help me out with what I think might be noob question.Here's my code:
def create
#project = Project.new(params[:project])
if #project.save
redirect_to new_project_path
end
student=#project.student_str.split(";")
#users = User.where(:code => student)
#users.each do |c|
puts c.email
end
#users.each do |c|
puts "I'm here"
c.projects = "#{c.projects};#{#project.id}"
end
end
So, in the create method, Each time a new project is created a string called student_str is stored where the ID number of each student is seperated by a ";". I split that string to an array using the split function to get an array of student ID's. I have the puts c.email and puts "I'm here" to make sure the loops are working fine. I get the proper outputs on terminal.
The problem here is the
c.projects = "#{c.projects};#{#project.id}"
That simply does not seem to be working.
My model is not updated when this line is executed. I get no errors though.
Can you tell me what I might have to do to fix this?
thanks!
You have to call c.save after you updated the projects attribute. Otherwise the object is updated but not the database so the next time you load it the changes are gone.

Resources