I have difficulties with ruby on rails syntax.
I got this error
First argument in form cannot contain nil or be empty
class PersonalsController
def index
end
def create
#personal = Personal.new
end
def new
#personal = Personal.new
end
def show
#personal = Personal.find([:id])
end
end
index.html.erb
<%= form_for #personal do |f| %>
<%= f.label :title %><br>
<%= f.text_field :title %>
<%= f.submit %>
<% end %>
the value of #personal is nil that's why you are getting error.
Change you code like this
def index
#personal= Personal.all
end
form_for is helper method
check with this link form_helper
The error is generated since #personal was not set in the controller. So either you add a #personal = Personal.new to the index method, or set it to a specific database entry, e.g., #personal = Personal.find(1)
However, it seems strange that you have a form displaying a single record in the index view.
More likely, you want to have the form in your new or edit views (in the former case you typically use new, while in the latter case you would use the find method to find a specific record and let the user edit it).
In the index method, you usually use the controller to select a group of records (e.g., #ps = Personal.all to get all the records) and iterate over them in the view (#ps.each do |person| .... end)
P.S. The show method should probably use Personal.find(params[:id]) instead of Personal.find([:id])
Related
i built this form that generate me some chebox with value like "U6", "U8" eccc
<%= form.label "Seleziona Categorie" %>
<% TeamCategory::NAMES.each do |category| %>
<%= check_box_tag 'categories_selected[]', category -%>
<% end %>
Now i have to pass the value of selected check_box to a method in my model.
Now is:
def create_tournament_team_categories
TeamCategory::NAMES.each do |name|
team_category = TeamCategory.where(name: name).first_or_create
self.tournament_team_categories << TournamentTeamCategory.create(team_category: team_category)
end
end
I would like to replace the TeamCategory::NAMES.each do with "selected check_box each do" and TeamCategory.where(name: name) with the value selected.
Thank you in advance
I am a newbie with Rails. What I see is that you took the part of the form to create the team, right?
For your code straight forward it could be:
<%= form.label "Seleziona Categorie" %>
<% TeamCategory::NAMES.each do |name| %> #you are looping through team category NAMES constant
<%= check_box_tag 'category_names_selected[]', name %>
<% end %>
Your form as is allows more than one category to be selected.
For the method:
def create_tournament_team_categories(category_names_selected)
category_names_selected.each do |name|
team_category = name
self.tournament_team_categories << TournamentTeamCategory.create(team_category: team_category)
end
end
you will probably use this method in your teams_controller.rb. In the controller, you should be able to retrieve from params a freshly created array of selected names with something along the lines with this.
#category_names_selected = params[:category_names_selected]
I do not know how complicated your app is so it might also be nested under ["team"][:category_names_selected] or ["team"]["category_names_selected"] in your params hash.
To see the exact structure of the params hash and adjust the equation above you can add for example require 'pry' at the top of your controller file and then but the binding.pry just after the part where your method is executed. When you restart the server and the app hits this part of the controller you should be able to see the exact structure of your params hash in the terminal.
You can then pass the array to the method that you can call in the controller. Do not forget to add :category_names_selected to the strong params in the controller. I hope this helps.
Controller on line 30
def create
#tournament = Tournament.new(tournament_params)
#tournament.sport_club = current_user.sport_club
#category_names_selected = params[:category_names_selected]
if #tournament.save
redirect_to tournaments_path, notice: 'Torneo creato con successo'
end
end
Method create_tournament_team_categories in the model
after_create :create_tournament_team_categories
def create_tournament_team_categories(category_names_selected)
#category_names_selected.each do |name|
team_category = name
self.tournament_team_categories << TournamentTeamCategory.create(team_category: team_category)
end
end
got a super quick question. I'm still new to rails and tried following these two questions but they didn't work for me:Why does Array.to_s return brackets? and ruby 1.9 how to convert array to string without brackets.
I'm trying to show the last message and the date in which it was sent out in my chatroom application. I am able to get the results using this code, but it has brackets around it and I would like to have those brackets removed. Any help here would be amazing, I've attached a screenshot as well. Thank you so much!
Show.html.erb
For the Date:
<%= chatroom.messages.last(1).pluck(:created_at) %>
For the Last Message in Chatroom:
<%= chatroom.messages.last(1).pluck(:body) %>
DirectMessages Controller
class DirectMessagesController < ApplicationController
before_action :authenticate_user!
def show
users = [current_user, User.find(params[:id])]
#messageduser = User.find(params[:id])
#chatroom = Chatroom.direct_message_for_users(users)
#chatroomall = current_user.chatrooms
#messages = #chatroom.messages.order(created_at: :desc).limit(100).reverse
#messagelast = #chatroom.messages.last(1)
last_message = #chatroom.messages.last
render "chatrooms/show"
end
private
def chatroomuserlocator
#chatroomlocator = Chatroom.find(params[:chatroom_id])
end
end
Try this:
<%= chatroom.messages.last.created_at %>
And this:
<%= chatroom.messages.last.body %>
Keep in mind that pluck returns an array, so that would explain your brackets.
I don't think you need pluck here since you are just accessing an attribute on a single item.
If you're not too worried about memory usage, you can fetch the whole object and only access the fields you want.
<%= chatroom.messages.last.created_at %>
<%= chatroom.messages.last.body %>
You can assign the lookup to a value, so it doesn't run twice:
last_message = chatroom.messages.last
Then you can access the attributes efficiently:
last_message.created_at
last_message.body
If you are interested in limiting the attributes or last_message, use select:
last_message = chatroom.messages.select(:created_at, :body).last
Putting it all together:
<% last_message = chatroom.messages.select(:created_at, :body).last %>
<%= last_message.created_at %>
<%= last_message.body %>
I’m new to rails and I’ve a pretty simple situation to solve but I cannot figure out how to proceed with it.
I want to create a simple ‘Setting’ model with key, value attributes. ‘SettingsController’ may contain 2 public methods only index and update. Only index action will have a view file with a form whose fields will represent each record of the ‘Settings’ table.
I want to be able to define some permitted keys (may be using some private method) and I want the form to create or update the record of relevant fields on submitting the form to update action.
Now, I don’t know exactly what code should I use in controller for index and update actions and in the index view file for the form which can create/update multiple records at the same time and can show updated values all the time. How do I proceed with it?
Update # 1:
I've managed to write some controller actions as below (based on some tutorial):
class Admin::SettingsController < ApplicationController
def index
#settings = Setting.all
end
def update
setting_params.each do |key, value|
Setting.where(key: key).first.update_attribute :value, value
end
redirect_to admin_settings_path, notice: "Settings saved."
end
private
def setting_params
params.require(:settings).permit(:site_title, :site_desc)
end
end
The form code in index view template is given below:
<h1>Settings</h1>
<%= form_tag admin_settings_path, method: "put" do %>
<p>
<label>Site Title:</label>
<%= text_field_tag "settings[site_title]" %>
</p>
<p>
<label>Site Description:</label>
<%= text_field_tag "settings[site_desc]" %>
</p>
<p>
<%= submit_tag "Save settings" %>
</p>
<% end %>
This forms saves the values correctly in the database but the saved values doesn't persist in form fields.
Maybe the problem is in the index action. Setting.all returns an array of Setting record, not a hash like { key1: value, key2: value } which I think you are trying to achieve. The form, therefore, displays data improperly. You can try this:
def index
#setting = {}
pairs = Setting.pluck(:key, :value)
pairs.each { |key, value| #setting[key] = value }
#setting
end
I have a page (mytestpage.html.erb) located at app/views/users/mytestpage.html.erb.
I've created a new table in my database called "Categories".
I'm trying to create a dropdown menu that lists all of the categories (:title string) on my mytestpage.html.erb page and I'm getting this error:
uninitialized constant UsersController::Categories
Here is my users_controller.rb
def mytestpage
#user = User.new
#categories = Categories.new
end
And here is my users/mytestpage.html.erb file:
<%= form_for categories do |f| %>
<%= f.collection_select(:title, Categories.all, :title, :description) %>
<% end %>
I assume that I wouldn't define #categories in my user_controller.rb (even though the file is located in my users folder - while I tried it, doing so throws me the same error).
It looks like you haven't created a model file for your Categories table. Something as simple as this:
class Category < ActiveRecord::Base
end
Should do the trick.
You will notice that I have named the class Category instead of Categories and this is due to the fact that Rails expects class names in singular form (eg User instead of Users) as it can infer the pluralised table name from the singular class name.
1. Use the instance variable instead of a constant in your view at app/views/users/mytestpage.html.erb:
<%= form_for categories do |f| %>
<%= f.collection_select(:title, #categories, :title, :description) %>
<% end %>
You're currently referencing a constant in the view. What you should be doing is referencing the instance variable that you've created in users_controller.rb
Instance variables are prefixed with # and are made available in the view that corresponds with the controller action that they are defined in.
2. Change your instance variable definition to this:
#categories = Category.new
or
#categories = Category.all
Right now you've got it defined as Categories.new and I don't think that's what you want to do - that is likely also why you're getting the error.
(depending on what you want to do - I feel like you might want to show all of the categories in you select tag? correct me if I'm wrong.)
I am trying to upload a photo but after I press the upload button, I get this error. I am new to rails 4 so I'm not sure what I am missing.
My logic is when I click the submit button. This will cause the create action to fire and create a IncomePicture object and store it in my database.
No route matches [POST] "/income_pictures/new"
Routes:
root_path GET / static_pages#home
income_pictures_path GET /income_pictures(.:format) income_pictures#index
POST /income_pictures(.:format) income_pictures#create
new_income_picture_path GET /income_pictures/new(.:format) income_pictures#new
edit_income_picture_path GET /income_pictures/:id/edit(.:format) income_pictures#edit
income_picture_path GET /income_pictures/:id(.:format) income_pictures#show
PATCH /income_pictures/:id(.:format) income_pictures#update
PUT /income_pictures/:id(.:format) income_pictures#update
DELETE /income_pictures/:id(.:format) income_pictures#destroy
Controller:
class IncomePicturesController < ApplicationController
def new
#income_picture = IncomePicture.new
end
def create
#income_picture = IncomePicture.new(IncomePicture_params)
if #income_picture.save
flash[:notice] = "Income picture successfully uploaded"
redirect_to #income_picture
end
end
def show
#income_picture = IncomePicture.find(params[:id])
end
def index
#income_picture = IncomePicture.all
end
private
def IncomePicture_params
params.require(:income_picture).permit(:image, :name)
end
end
View:
<%= form_for :income_picture, :html => { :multipart => true } do |f| %>
<p>
<%= f.label :name %>
<%= f.text_field :name %>
</p>
<p>
<%= f.label :image %>
<%= f.file_field :image %>
</p>
<p><%= f.submit %></p>
<% end %>
I think you want form_for #income_picture rather than form_for :income_picture.
From the form guide: Using a symbol creates a form to new_income_picture_path, i.e. /income_picture/new whereas using a populated instance variable creates a form to income_pictures_path, i.e. income/pictures. Both set the form's method to POST. However, there's no such route as POSTing to /income_picture/new/, which is what caused the error.
form_for
To elaborate on the accepted answer, you have to remember that when calling form_for, Rails does some pretty amazing things:
It takes an ActiveRecord object and builds a "route" out of it (from the model)
It populates the form with the ActiveRecord object's data
It allows you to retain a perceived persistent state on the form (by perpetuating the data)
The problem you have is you're passing a simple symbol to the form - which prevents Rails from being able to accurately access the data required to make the 3 "magic" steps above possible.
This means you'll get random errors like the one you're seeing (IE in the absence of an ActiveRecord object, Rails will just use the same URL that you have on your page - /new)
--
ActiveRecord
The way to fix the issue you have is to replace the symbol with an ActiveRecord object, which was suggested in the accepted answer.
The reason why using an ActiveRecord object (#instance_variable) works is because of Ruby's core functionality -- it's a object orientated language. Being object orientated, it means that each time you populate an ActiveRecord object, you'll basically give Rails a series of other information, such as model_name etc.
This means when you pass the #instance_variable to the form_for method, Rails will be able to take the data from ActiveRecord & process it on screen for you