I'm new to rails and I'm working on a project where I'm having an issue. I'm trying to display all the gyms that have the same zipcode. When I tried the code below, it only displays 1 and not the other ones. How can display all the gym that have the same zip code?
controller
def gym
#fitness = Fitness.find_by(zip_code: params[:zip_code])
end
gym.html.erb
<%= #fitness.name %>
You're doing this to yourself. By definition, #find_by only returns a single record, or nil. You probably want #where instead:
Fitness.where(zip_code: params[:zip_code])
If that still doesn't work, check both your table data and the content of your params hash to make sure you're creating a valid query.
def gyms
#fitness = Fitness.where("zip_code = ?", params[:zip_code])
end
Related
I want to find records on the bases of demo_id from Demojobs model.
def show
#demojob = Demojob.find params[:demo_id] #instead of params[:id]
end
but it shows a error Couldn't find Demojob without an ID
Use .find_by
#demojob = Demojob.find_by(demo_id: params[:demo_id])
EDIT:
For Rails version lower than 4.0.2, use:
#demojob = Demojob.where(demo_id: params[:demo_id]).first
I am working on a Rails app, and I am attempting to insert attributes from JSONs as database entries. I'm running into a problem, though, and would appreciate some guidance.
I've been able to jam a few things together and come up with something that sort of works...
def create
#report_group = Array.new
#report_group.push({location:"home", comments:"Hello, database!"}, {location:"away", comments:"Goodbye, database!"})
#report_group.each do |x|
#new_report = Report.new(x)
#new_report.user_id = current_user.id
#new_report.save
end
end
private
def report_params(params)
params.permit(:user_id,:location,:comments)
end
This is a good first step - this commits two entries to my database, one for each of the hashes pushed into #report_group, but it is suffering from a problem - the create action does not reference the report_params whitelist.
I have built several Rails apps where entries are submitted one at a time via the standard Rails form helpers, but I have never done it with multiple JSONs like this before. Trying out the syntax I'd use in a typical form helper situation
#new_report = Report.new(report_params(x))
throws the expectable error undefined method permit' for #<Hash:0x007f966b35e270> but I am not sure what else to do here.
EDIT TO SHOW SOLUTION
Big thanks to #oreoluwa for pointing me in the right direction. Here's the solution that I came up with.
def create
#report_group = Array.new
#report_group.push({location:"home", comments:"Hello, database!"}, {location:"away", comments:"Goodbye, database!"})
#report_group.each do |x|
hash = ActionController::Parameters.new(x)
#new_report = Report.new(report_params(hash))
#new_report.user_id = current_user.id
#new_report.save
end
end
private
def report_params(params)
params.permit(:user_id,:location,:comments)
end
You're getting the error because a Hash is not the same as an ActionController::Parameters. In order to use the permit method with your Hash you may need to first convert it to ActionController::Parameters, as such:
hash = {location:"home", comments:"Hello, database!"}
parameter = ActionController::Parameters.new(hash)
parameter.permit(:user_id,:location,:comments)
I don't know if that is what you're looking for, but I thought to point you in the right direction.
I have a problem for redirecting back after an action.
My condition is this:
Client, Volunteer, and staff has many next of kin. After creating a new next of kin, I want to redirect back to edit page of a particular client/volunteer/staff.
my current solution is this.
For the link to add
<%= link_to new_admin_people_next_of_kin_path(source: source,
source_id: source_id),
class: 'js-btn-add btn btn-success btn-sm' do %>
Add New Next of Kin
<% end %>
where
source = :client/:staff/:volunteer
source_id = id(primary key) or the staff/volunteer/client
my new method
def new
#person = Person.new
#person.source = params[:source]
#person.source_id = params[:source_id]
end
later I will pass source and source_id as hidden parameter.
my people_controller create method(because next of kin is a person)
def create
if params[:source] == 'client'
#client = Client.find(params[:source_id])
#pnok = #client.people_next_of_kin.build
elsif params[:source] == 'volunteer'
#volunteer = Volunteer.find(params[:source_id])
#pnok = #volunteer.people_next_of_kin.build
elsif params[:source] == 'staff'
#staff = Staff.find(params[:source_id])
#pnok = #staff.people_next_of_kin.build
else
#pnok = PeopleNextOfKin.new
end
#person = #pnok.build_next_of_kin
Person.transaction do
#person.update_attributes(create_params)
#person.save(validate: false)
end
end
as you can see, it's not really clean and hardcoded. I have read on polymorphic path, but I can't really find a way to use that for my solution as I need to build a new next of kin first and I cannot pass in an object in link_to or redirect_to, and then there's also a problem whereby the next of kin is not saved yet in database, so I cannot use person.find.
any solution?
It's a little tough to see what you are after from your example. I would guess that you want to redirect back to the staff / volunteer / client page and there would be a Parent / Child relationship with a NOK.
However, it's unclear what your models look like. For example, you might be using single table inheritance and polymorphism because these are all "People", or you might have the relationships in your models. I think the solution depends on which path you take.
For example, you might use something like this:
def Client
has_many :noks
end
If you had that, you could build the empty :nok record and then redirect back to the :client, and let the Rails / ActiveRecord internals manage the relationship. For example, the Client #show page may have places to list all Next of Kins that enumerates all of the kin.
Summary: I think you are trying to do too much in your controller without using models the way that RoR supports.
Rails (and coding) rookie here (I'm sure I'm just missing basic syntax structural stuff), I've created a form where the user can add as many field pairs as they like via AJAX (barely). This form will collect column titles for a 'sheet' and the associated data type (int, str... etc). The sheet will have item entries added later by users. I'm trying to make a Sheets controller create method that not only saves the title and description of the sheet, but also adds a record to the 'columns' table with the column title, data type and associated sheet id. When I submit the sheet form, I get the following params in the server terminal:
(sorry I'm not sure how to wrap the code snippet)
{"utf8"=>"✓", "authenticity_token"=>"yMlnfO1EWptkEXp5+9AGCO5C3vHt62EUHoKjdWoUB8I=", "sheet"=>{"title"=>"test 33", "description"=>"Descriptions"}, "column"=>[{"title"=>"1", "type"=>"num"}, {"title"=>"2", "type"=>"int"}, {"title"=>"3", "type"=>"real"}, {"title"=>"fo", "type"=>"no"}], "commit"=>"Save Specsheet!"}
I'm trying to loop through the column hash to create a record on the columns table. Each hash would use the title and type values as entries on the table.
My create method:
def create
#sheet = Sheet.new(sheet_params)
#sheet[:column].each do |key, value|
#column = Column.new
#column[:column_title] = key
#column[:column_data_type] = value
#column.save
end
if #sheet.save
redirect_to #sheet
else
flash[:error] = "Error saving sheet."
render :new
end
end
My error is usually something like this:
undefined method `each' for nil:NilClass
**#sheet[:column].each do |key, value|**
#column = Column.new
#column[:column_title] = key
#column[:column_data_type] = value
So I know I'm messing up referencing the column hash and its key and values. I'm thinking I can .reduce something here? I have no idea. These kinds of basic structural questions don’t really show up with googling, so please let me know what I'm doing wrong, and thank you for reading all of this! Cheers!
WORKING CODE (sorry for weird formatting)
def create
#sheet = Sheet.new(sheet_params)
column_params.each do |value|
#sheet.columns.build(value.permit(:title, :data_type))
end
if #sheet.save
redirect_to #sheet
else
flash[:error] = "Error saving sheet."
render :new
end
end
private
def sheet_params
params.require(:sheet).permit(:title, :description, :created_at, :updated_at, :column)
end
def column_params
params.require(:column)
end
When you are calling #sheet[:column], you are referencing an instance of Sheet instead of the params that you are trying to cycle through.
If you are trying to associate Columns to Sheets in a has_many relationship, you can create Columns like:
column.each do |key, value|
#sheet.columns.new(
column_title: key
column_data_type: value
end
end
(and then save block)
in your controller. Where column are the params. This will indicate that the column belongs to the sheet instance.
If you are trying to make the Column record without the associations, you can do
column.each do |key, value|
Column.new(
column_title: key
column_data_type: value
end
end
(and then save block)
(Both assuming that your fields are named column_title and not just title.)
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.