created micropost with t.text :content, results in unpermitted parameter "text" - ruby-on-rails

I've created a basic devise login with microposts which have :user_id from :users, and t.text :content. If it matters I generated this with a scaffold content:text. Here is the micropost controller:
class MicropostsController < ApplicationController
def new
#micropost = Micropost.new
end
def create
#micropost = Micropost.create(params[:content])
respond_to do |format|
if #micropost.save!
format.html { redirect_to microposts_path, notice: 'Micropost was successfully created.' }
format.json { render :show, status: :created, location: #micropost }
else
format.html { render :new }
format.json { render json: #micropost.errors, status: :unprocessable_entity }
end
end
end
private
def micropost_params
params.require(:micropost).permit( :content)
end
end
However everytime I try and create/save a 'micropost' is results in 'unpermitted parameter:text'? Any help is appreciated.
_form.html.erb
<%= form_with(model: micropost, local: true) do |form| %>
<% if micropost.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(micropost.errors.count, "error") %> prohibited this micropost from being saved:</h2>
<ul>
<% micropost.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.text_field :text %>
</div>
<div class="actions">
<%= form.submit %>
</div>
<% end %>

The field in your form is text but your fields name is content. Change the text field in your form to :content.

This was just laziness on my part, the micropost new.html.erb had no form.label or form.text_are, additionally #micropost = Micropost.create was typed wrong as #micropost.create. Sorry guys!

Related

Ruby on Rails: How to extract URL parameter and insert the value inside a variable

I need to extract a parameter from my url and insert it into my database for a referral system.
Let's say this user, which is id = 1 has shared his link with another user, the url would be:
https://www.example.com/signup?referredBy=1
When the new user creates his account, I want the field referredBy to be assigned with the value from the referredBy parameter, which should be an Integer.
I've tried to do
#user.referredBy = [:referredBy]
But it didn't worked out.
Any help is appreciated.
Thank you so much.
EDIT
My index.html.erb is:
<% if current_user %>
Logged in as <%= current_user.nomeUsuario %>
<%= link_to "Log out", logout_path %>
<% end %>
<p id=”notice”><%= notice %></p>
<% else %>
<%= link_to "Sign up", signup_path %>
<%= link_to "Log in", login_path %>
<% end %>
My new.html.erb is:
<h1>New User</h1>
<% if current_user %>
<% controller.redirect_to root_url %>
<% else %>
<%= render 'form', user: #user %>
<%= link_to 'Back', login_url %>
<% end %>
My _form.html.erb is:
<%= form_with(model: user) do |form| %>
<% if user.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(user.errors.count, "error") %> prohibited this user from being saved:</h2>
<ul>
<% user.errors.each do |error| %>
<li><%= error.full_message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= form.label :name, "Full Name" %>
<%= form.text_field :nomeUsuario %>
</div>
<div class="field">
<%= form.label :name, "E-mail" %>
<%= form.text_field :email %>
</div>
<div class="field">
<%= form.label :name, "Password" %>
<%= form.password_field :password %>
</div>
<div class="field">
<%= form.label :name, "Password Confirmation" %>
<%= form.password_field :password_confirmation %>
</div>
<div class="field">
<%= form.label :name, "Tipo do Plano" %>
<%= form.select :tipoPlano, ["Gratuito", "Mensal", "Anual"], selected: "Gratuito" %>
</div>
<%= form.hidden_field :indicadoPor, params[:indicadoPor] %>
<div class="actions">
<%= form.submit %>
</div>
<% end %>
My user_controller.rb is:
class UsersController < ApplicationController
before_action :set_user, only: %i[ show edit update destroy ]
# GET /users/new
def new
#user = User.new
end
# GET /users/1/edit
def edit
end
# POST /users or /users.json
def create
#user = User.new(user_params)
set_tipoPlano
#user.indicadoPor = params[:indicadoPor]
respond_to do |format|
if #user.save
format.html { redirect_to root_url, notice: "User was successfully created." }
format.json { render root_url, status: :created, location: #user }
else
format.html { render :new, status: :unprocessable_entity }
format.json { render json: #user.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /users/1 or /users/1.json
def update
respond_to do |format|
if #user.update(user_params)
set_tipoPlano
format.html { redirect_to root_url, notice: "User was successfully updated." }
format.json { render :show, status: :ok, location: #user }
else
format.html { render :edit, status: :unprocessable_entity }
format.json { render json: #user.errors, status: :unprocessable_entity }
end
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_user
#user = User.find(params[:id])
end
# Only allow a list of trusted parameters through.
def user_params
params.require(:user).permit(:email, :password, :password_confirmation, :nomeUsuario, :tipoPlano, :valorPlano, :indicadoPor, :comissaoAcumuladaAtual, :comissaoASerRetirada)
end
def set_tipoPlano
if(#user.tipoPlano == "Gratuito")
#user.valorPlano = 0.0
elsif(#user.tipoPlano == "Mensal")
#user.valorPlano = 49.90
elsif(#user.tipoPlano == "Anual")
#user.valorPlano = 39.90
end
end
end
If you need something else, please let me know! Thank you so much for the help.
ANSWER BELOW
I've fixed it.
I just had to change my form to:
<%= form.hidden_field :indicadoPor, value: params[:indicadoPor] %>
I forgot the =, so the form wasn't being rendered. Also, I've removed the #user.referredBy = params[:referredBy] from my controller. Everything is fine now.
Thank you guys, gals and non-binaries for the help so far!
[:referral]
This is an array with a single value. That value is a symbol :referral.
I'm not sure what type your referredBy column is but it's almost certainly going to complain about being given an array of symbols.
You want
params[:referral]
params is a hash like object containing the params in the url/(and sometimes body). So params[:referral] looks up the :referral symbol in the params hash and returns whatever the user provided.

NoMethodError in Profiles#show undefined method `about' for nil:NilClass

I am currently re-working my routes, which leads to a lot of mistakes in my Rails App. I am coming from something like
users/:user_id/profiles/id/reviews
to
/users/:user_id/profile/reviews
After registering a user gets redirected (redirect_after_sign_up) to a profile
/users/:user_id/profile/new
where the user can fill out the form (a allow nested attributes for profile)
<%= form_for(#user, url: user_profile_path, method: :post) do |form| %>
<div class="field">
<%= form.label :street %>
<%= form.text_area :street %>
</div>
<%= fields_for(:profile) do |profile_fields| %>
<div class="field">
<%= profile_fields.label :about %>
<%= profile_fields.text_area :about %>
</div>
<div class="field">
<%= profile_fields.file_field :avatar %>
<% profile_fields.label "Profile photo" %>
</div>
<% end %>
<div class="actions">
<%= form.submit "Save your profile", class: "btn btn-default" %>
</div>
<% end %>
After I click submit, these data won't save anywhere. The user also won't get redirected to the #show, as, there are obviously some problems with my profiles controller. Neither #show, nor #create works. Here is the controller
class ProfilesController < ApplicationController
before_action :set_profile, only: [:show, :edit, :update, :destroy]
def show
#profile = current_user.profile
#review = Review.new
Review.where(profile: #profile)
end
def new
#user = User.eager_load(:profile).find(params[:user_id])
#profile = Profile.new
end
def edit
#profile = #user.profile
end
def create
#user = current_user
#profile = current_user.build_profile(profile_params)
respond_to do |format|
if #profile.save
format.html { redirect_to user_profile_path(current_user.id), notice: 'Profile was successfully created.' }
format.json { render :show, status: :created, location: #profile }
else
format.html { render :new }
format.json { render json: #profile.errors, status: :unprocessable_entity }
end
end
end
def update
respond_to do |format|
if #profile.update(profile_params)
format.html { redirect_to user_profile_path(current_user.id), notice: 'Profile was successfully updated.' }
format.json { render :show, status: :ok, location: #profile }
else
format.html { render :edit }
format.json { render json: #profile.errors, status: :unprocessable_entity }
end
end
end
# DELETE /profiles/1
# DELETE /profiles/1.json
def destroy
#profile.destroy
respond_to do |format|
format.html { redirect_to users_url, notice: 'Profile was successfully destroyed.' }
format.json { head :no_content }
end
end
private
def set_profile
#profile = current_user.profile
end
def profile_params
params.permit(:about, :avatar)
end
end
I really need help adjusting the controller, so it works without a profile_id. Here is the show page, just in case:
<% if #profile == current_user.profile %>
<strong> Welcome </strong><%= current_user.first_name %>
<% else %>
<strong> This is a profile of </strong><%= #profile.user.first_name %> <%= #profile.user.last_name %>
<% end %>
<p>
<strong>About:</strong>
<%= #profile.about %>
</p>
<strong>Profile image</strong>
<%= image_tag(url_for(#profile.avatar), style: 'width:50px; height:50px;') %>
</p>
<%= render 'reviews/form' %>
<% #reviews.each do |review| %>
<%= review.user.first_name %> <%= review.user.last_name %> wrote <small> <%= time_ago_in_words(review.created_at) %> ago </small>
<p>
<%= review.content %>
<br>
<strong> Rating </strong><%= review.rating %>
</p>
<% end %>
<%= link_to 'Edit', edit_user_profile(current_user.profile) %>
<%= link_to 'Show other profiles', users_path %>
<div class="container">
Thank you.
P.S. I tried to work with a ProfileController (single), but this didn't work at all, as the app wouldn't find the controller.
UPDATE:
So, I tried to play with the form, looks like the form won't save neither to profile nor to user. Even if I get rid of the nested attributes, it still doesn't save. This stays unresoled ...
as i can see you're using fields_for, so check a structure od params which are send when posting. I suppose they may look like:
user: { :street, profile_attributes: { :about, :avatar } }
and if yes, you need to change the permitted params method to match what is actually send.
Next advise is to add accepts_nested_attributes_for :profile in user model, and use fields_for proper way by saving profile in addition to saving user, because current code is little messy (form_for user with fields for profile leading to profile controller).
If you don't wan't to deal with nested attributes you may also rewrite form as form_for #profile ...

Add data to table referenced with foreign key in Rails

I have two models: Question and Options. Question has has_many relation with Options. I need to add options to question whenever I create a new question. I have written the code but I am not able to send data to the options of Question model. Whenever I create the question and add options in the form, the options to that question are empty. Where is the mistake?
Models
class Question < ApplicationRecord
belongs_to :user
has_many :options
accepts_nested_attributes_for :options
end
class Option < ApplicationRecord
belongs_to :question
end
questions_controller.rb
# GET /questions/new
def new
#question = Question.new
#question.options.build(params[:options])
end
# GET /questions/1/edit
def edit
end
# POST /questions
# POST /questions.json
def create
#question = Question.new(question_params)
puts("---------------------Question options: --------------------------------------------")
puts(#question.options)
#question.user = current_user
respond_to do |format|
if #question.save
format.html { redirect_to #question, notice: 'Question was successfully created.' }
format.json { render :show, status: :created, location: #question }
else
format.html { render :new }
format.json { render json: #question.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /questions/1
# PATCH/PUT /questions/1.json
def update
respond_to do |format|
if #question.update(question_params)
format.html { redirect_to #question, notice: 'Question was successfully updated.' }
format.json { render :show, status: :ok, location: #question }
else
format.html { render :edit }
format.json { render json: #question.errors, status: :unprocessable_entity }
end
end
_form.html.erb
<%= form_with(model: question, local: true) do |form| %>
<% if question.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(question.errors.count, "error") %> prohibited this question from being saved:</h2>
<ul>
<% question.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= form.label :body %>
<%= form.text_area :body %>
</div>
<%= form.fields_for :address do |a| %>
<div class="field">
<%= a.label :option1 %>
<%= a.text_area :body %>
</div>
<div class="field">
<%= a.label :option2 %>
<%= a.text_area :body %>
</div>
<% end %>
<div class="actions">
<%= form.submit %>
</div>
<% end %>
For this case, I strongly recommend using a FormObject in place of accepts_nested_attributes_for. Here is a quick video on how to implement a FormObject. https://thoughtbot.com/upcase/videos/form_objects
Also, there is a related discussion here on why accepts_nested_attributes_for is not a great option.

Rails saving all my fields as nil

It creates the object, says that it was successfully created, but all fields are saved in the database with nil values. Only created_at and updated_at are saved normally.
Some methods of my controllers/admin/categories_controller.rb
def new
#admin_category = Category.new
end
# GET /admin/categories/1/edit
def edit
end
# POST /admin/categories
# POST /admin/categories.json
def create
#admin_category = Category.new(params[:category])
respond_to do |format|
if #admin_category.save
format.html { redirect_to admin_category_path(#admin_category), notice: 'Category was successfully created.' }
format.json { render :show, status: :created, location: admin_category_path(#admin_category) }
else
format.html { render :new }
format.json { render json: #admin_category.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /admin/categories/1
# PATCH/PUT /admin/categories/1.json
def update
respond_to do |format|
if #admin_category.update(admin_category_params)
format.html { redirect_to #admin_category, notice: 'Category was successfully updated.' }
format.json { render :show, status: :ok, location: #admin_category }
else
format.html { render :edit }
format.json { render json: #admin_category.errors, status: :unprocessable_entity }
end
end
end
This is my models/category model:
class Category < ActiveRecord::Base
belongs_to :category
end
This is my routes.br file
namespace :admin do
resources :categories
end
My views/admin/categories/_form.html.erb
<%= form_for(#admin_category, url: admin_categories_path) do |f| %>
<% if #admin_category.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#admin_category.errors.count, "error") %> prohibited this admin_category from being saved:</h2>
<ul>
<% #admin_category.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :name %><br>
<%= f.text_field :name %>
</div>
<div class="field">
<%= f.label :is_active %><br>
<%= f.check_box :is_active %>
</div>
<div class="field">
<%= f.label :main_menu %><br>
<%= f.check_box :main_menu %>
</div>
<div class="field">
<%= f.label :category_id %><br>
<%= f.number_field :category_id %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
And when I try to edit, I get this error:
No route matches [PATCH] "/admin/categories"
I'm very newbie to Ruby on Rails, so I would apreciate any help!
Thanks!
You are only passing :category when creating a new Category:
def create
#admin_category = Category.new(params[:category])
Change it to Category.new(user_params) and try again. This will pass on all parameters you're creating and feed it to the database.
Also, permit the parameters you are trying to pass:
def user_params
params.require(:admin_category).permit(:name, :is_active, :main_menu, :category_id)
end
Strong Params:
#app/controllers/categories_controller.rb
class CategoriesController < ApplicationController
def create
#admin_category = Category.new category_params
end
private
def category_params
params.require(:category).permit(:name, :is_active, :main_menu, :category_id)
end
end
--
As a tip, if you're using nested objects with forms, you can pass both objects in an array to create the nested path:
#app/views/admin/categories/new.html.erb
<%= form_for [:admin, #admin_category] do |f| %>

Rails: Datetime params are empty?

In my post view, I have a _form with a title and releaseDate parameter.
In my controller I get the value from params[:post][:title], but the params[:post][:releaseDate] is empty.
post _form
<%= form_for(#post) do |f| %>
<% if #post.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#post.errors.count, "error") %> prohibited this post from being saved:</h2>
<ul>
<% #post.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :title %><br />
<%= f.text_field :title %>
</div>
<div class="field">
<%= f.label :releaseDate %><br />
<%= f.datetime_select :releaseDate %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
posts_controller
def create
#title = params[:post][:title]
#date = params[:post][:releaseDate]
#post = Post.new(title: #title, releaseDate: #date)
#post.user_id = current_user.id
respond_to do |format|
if #post.save
format.html { redirect_to #post, notice: 'Post was successfully created.' }
format.json { render json: #post, status: :created, location: #post }
else
format.html { render action: "new" }
format.json { render json: #post.errors, status: :unprocessable_entity }
end
end
end
(I am not using #post = Post.new(params[:post]) because I want to do something with the title and releaseDate in the controller.)
post.rb (model)
class Post < ActiveRecord::Base
attr_accessible :releaseDate, :title, :user_id
belongs_to :user
end
Any suggestions on how I can get the datetime value from the form and into my controller?
releaseDate is not rails convention, try to rename field to release_date. Maybe this will help.
To proof this concept you can use so called virtual attributes: add release_date getter and setter to model like this (note that logs can help you to narrow down the problem) :
class Post < ActiveRecord::Base
attr_accessible :releaseDate, :title, :user_id
belongs_to :user
def release_date
date = read_attribute('releaseDate')
logger.debug("READ DATE IS #{date} aND CLASS IS #{date.class}") # see this in rails server logs
end
def release_date=(date)
logger.debug("WRITE DATE IS #{date} aND CLASS IS #{date.class}") # see this in rails server logs
write_attribute('releaseDate', date)
end
end
And in view replace all releaseDate with release_date

Resources