Warning, I'm a newb and trying to learn RoR on my own. Been doing the tutorials etc and now trying to learn through experience. Long story short I'm trying to attach a user picture from a url defined by them, with a default pic if they don't supply one. Been running into all kinds of errors, I think I have it down to one primary issue now after hours of trying to figure it all out (since I'm new at this). So right now the error I'm getting is:
NoMethodError in GravsController#update
undefined method `update_attributes' for nil:NilClass
I know this means I need to do something like:
#something = Model.new/build(params[:method])
But I don't know where to define it in my controller (I'm guessing the gravs_controller right?) So here's my code, tear it apart and see if you can help me get this image function working, please :)
class GravsController < ApplicationController
before_filter :signed_in_user
gravs_controller
def create
#graver = current_user.gravs.new(params[:content])
#grav_bool = false
if #graver.save
#grav_bool = true
#grav_bool.save
flash[:success] = "User Picture Saved!"
redirect_to faq_path
else
#grav_bool = false
#grav_bool.save
redirect_to faq_path
end
end
def update
if #graver.update_attributes(params[:content])
#grav_bool = true
#grav_bool.save
flash[:success] = "User Picture Saved!"
redirect_to faq_path
else
#grav_bool = false
#grav_bool.save
redirect_to faq_path
end
end
end
users_controller
class UsersController < ApplicationController
before_filter :signed_in_user, only: [:index, :edit, :update, :destroy, :gravs]
before_filter :correct_user, only: [:edit, :update, :gravs]
before_filter :admin_user, only: :destroy
def index
#users = User.paginate(page: params[:page])
end
def show
#user = User.find(params[:id])
#microposts = #user.microposts.paginate(page: params[:page])
end
def new
#user = User.new
end
def create
#user = User.new(params[:user])
if #user.save
sign_in #user
flash[:success] = "Welcome to Inception!"
redirect_to gravs_path
else
render 'new'
end
end
def edit
end
def update
if #user.update_attributes(params[:user])
sign_in #user
flash[:success] = "Profile updated"
redirect_to gravsid_path
else
render 'edit'
end
end
def destroy
User.find(params[:id]).destroy
flash[:success] = "User deleted"
redirect_to users_path
end
private
def correct_user
#user = User.find(params[:id])
redirect_to (root_path), error: "Cannot edit others information!" unless current_user?(#user)
end
def admin_user
redirect_to(root_path) unless current_user.admin?
end
end
create.html.erb (Inside /views/gravs/)
<% provide(:title, "Edit Picture") %>
<div class="barney">
<div class="trouble">
<h1>Update Your Picture</h1>
<%= gravs_display #graver %>
<%= form_for(:grav) do |f| %>
<div class="field">
<%= f.text_field :content, placeholder: "Enter Picture URL" %>
</div>
<%= f.submit "Update User Image", class: "btn btn-small btn-primary" %>
<% end %>
</div>
</div>
update.html.erb (inside /views/gravs/)
<% provide(:title, "Edit Picture") %>
<div class="barney">
<div class="trouble">
<div class="row">
<div class="span6 offset3">
<h1>Update Your Picture</h1>
<%= gravs_display #graver %>
<%= form_for(:gravs) do |f| %>
<div class="field">
<%= f.text_field :content, placeholder: "Update Picture URL" %>
</div>
<%= f.submit "Update User Image", class: "btn btn-small btn-primary" %>
<% end %>
</div>
</div>
</div>
</div>
** datenumber_create_gravs.rb**
class CreateGravs < ActiveRecord::Migration
def change
create_table :gravs do |t|
t.string :content
t.integer :user_id
end
end
end
schema.rb
ActiveRecord::Schema.define(:version => 20130407202835) do
create_table "gravs", :force => true do |t|
t.string "content"
t.integer "user_id"
end
create_table "microposts", :force => true do |t|
t.string "content"
t.integer "user_id"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
add_index "microposts", ["user_id", "created_at"], :name => "index_microposts_on_user_id_and_created_at"
create_table "users", :force => true do |t|
t.string "name"
t.string "email"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.string "password_digest"
t.string "remember_token"
t.boolean "admin", :default => false
end
add_index "users", ["email"], :name => "index_users_on_email", :unique => true
add_index "users", ["remember_token"], :name => "index_users_on_remember_token"
end
routes.rb
MydeaSample::Application.routes.draw do
resources :users
resources :sessions, only: [:new, :create, :destroy]
resources :microposts, only: [:create, :destroy]
root to: "static_pages#home"
match '/help', to: 'static_pages#help'
match '/about', to: 'static_pages#about'
match '/contact', to: 'static_pages#contact'
match '/signup', to: 'users#new'
match '/signin', to: 'sessions#new'
match '/signout', to: 'sessions#destroy', via: :delete
match '/message', to: 'static_pages#message'
match '/faq', to: 'static_pages#faq'
match '/gravs', to: 'gravs#create'
match '/gravsid', to: 'gravs#update'
Related
When I try and edit the Contact to add a DataType, I receive a: 'Unpermitted parameter: data_format' error. I have tried following similar associations I have found online, but can't figure out what I am missing. I apologize if this is redundant.
Here are the relevant pieces of information:
Models:
# == Schema Information
#
# Table name: contacts
#
# id :integer not null, primary key
# name :string
# email :string
# phone :string
# mobile :string
# created_at :datetime not null
# updated_at :datetime not null
# supplier_id :integer
#
class Contact < ActiveRecord::Base
has_one :data_type
accepts_nested_attributes_for :data_type, allow_destroy: true
end
# == Schema Information
#
# Table name: data_formats
#
# id :integer not null, primary key
# name :string
# created_at :datetime not null
# updated_at :datetime not null
# contact_id :integer
#
class DataFormat < ActiveRecord::Base
belongs_to :contact
end
Contact Controller:
class ContactsController < ApplicationController
before_action :set_contact, only: [:show, :edit, :update, :destroy]
def new
#contact = Contact.new
end
def create
#contact = Contact.new(contact_params)
respond_to do |format|
if #contact.save
format.html { redirect_to #contact, notice: 'Contact was successfully created.' }
format.json { render :show, status: :created, location: #contact }
else
format.html { render :new }
format.json { render json: #contact.errors, status: :unprocessable_entity }
end
end
end
private
def set_contact
#contact = Contact.find(params[:id])
end
def contact_params
params.require(:contact).permit(:name, :email, :phone, :mobile, :data_format,
data_format_attributes: [ :id, :name, :contact_id, :_destroy ] )
end
end
Edit View:
<%= simple_form_for #contact do |f| %>
<div class="form-group">
<div class="col-lg-6">
<%= f.input :name %>
</div>
<div class="col-lg-6">
<%= f.simple_fields_for :data_format do |t| %>
<%= t.input :id, label: 'Date Format:', :collection => DataFormat.order(:name) %>
<% end %>
</div>
<div class="col-lg-6">
<%= f.label "Submit", class: 'control-label' %>
<%= f.button :submit, class: 'btn btn-primary form-control' %>
</div>
</div>
<% end %>
The DataType(s) are appearing in the form and I can select them. So, I know the issue must be within the controller.
Any help would be greatly appreciated!
Your contact.rb is accepting nested attributes name and permitted parameters name mismatch. contact.rb mentions: accepts_nested_attributes_for :data_type, allow_destroy: true .
contact.rb
class Contact < ActiveRecord::Base
has_one :data_format
accepts_nested_attributes_for :data_format, allow_destroy: true
end
contacts_controller.rb
class ContactsController < ApplicationController
before_action :set_contact, only: [:show, :edit, :update, :destroy]
def new
#contact = Contact.new
#contact.data_format = DataFormat.new
end
...
private
def set_contact
#contact = Contact.find(params[:id])
end
def contact_params
params.require(:contact).permit(:name, :email, :phone, :mobile, :data_format,
data_format_attributes: [ :id, :name, :contact_id, :_destroy ] )
end
form
<%= simple_form_for #contact do |f| %>
<div class="form-group">
<div class="col-lg-6">
<%= f.input :name %>
</div>
<div class="col-lg-6">
<%= f.simple_fields_for :data_format, #contact.data_format do |t|%>
<%= t.input :id, label: 'Date Format:', :collection => DataFormat.order(:name) %>
<% end %>
</div>
<div class="col-lg-6">
<%= f.label "Submit", class: 'control-label' %>
<%= f.button :submit, class: 'btn btn-primary form-control' %>
</div>
</div>
<% end %>
So I want to create a Company while signing up as a new user to my application. I use https://github.com/thoughtbot/clearance for authentication.
I have these 2 migrations:
class CreateCompanies < ActiveRecord::Migration
def change
create_table :companies do |t|
t.string :name, null: false
t.string :email, null: false
t.attachment :logo
t.timestamps null: false
end
end
end
And
class CreateClearanceUsers < ActiveRecord::Migration
def change
create_table :users do |t|
t.string :email, null: false
t.string :encrypted_password, limit: 128, null: false
t.string :confirmation_token, limit: 128
t.string :remember_token, limit: 128, null: false
t.string :first_name
t.string :last_name
t.attachment :avatar
t.integer :company_id
t.timestamps null: false
end
add_index :users, :email, unique: true
add_index :users, :remember_token
end
end
My models look like this:
class User < ActiveRecord::Base
include Clearance::User
belongs_to :company
end
class Company < ActiveRecord::Base
has_many :users
accepts_nested_attributes_for :users
end
This is my altered Clearance controller:
class Clearance::UsersController < ApplicationController
before_filter :redirect_signed_in_users, only: [:create, :new]
skip_before_filter :require_login, only: [:create, :new]
skip_before_filter :authorize, only: [:create, :new]
def new
#user = User.new
#user.build_company
render template: "users/new"
end
def create
#user = User.new(user_params)
if #user.save
sign_in #user
redirect_back_or url_after_create
else
render template: "users/new"
end
end
private
def avoid_sign_in
warn "[DEPRECATION] Clearance's `avoid_sign_in` before_filter is " +
"deprecated. Use `redirect_signed_in_users` instead. " +
"Be sure to update any instances of `skip_before_filter :avoid_sign_in`" +
" or `skip_before_action :avoid_sign_in` as well"
redirect_signed_in_users
end
def redirect_signed_in_users
if signed_in?
redirect_to Clearance.configuration.redirect_url
end
end
def url_after_create
Clearance.configuration.redirect_url
end
def user_params
params.require(:user).permit(:first_name, :last_name, :email, :password, companies_attributes: [:id, :name])
end
end
And at last my form:
<div class="form-item">
<%= form.label :first_name %>
<%= form.text_field :first_name, type: "text" %>
</div>
<div class="form-item">
<%= form.label :last_name %>
<%= form.text_field :last_name, type: "text" %>
</div>
<div class="form-item">
<%= form.label :email %>
<%= form.text_field :email, type: "email" %>
</div>
<div class="form-item">
<%= form.fields_for :companies do |builder| %>
<label>Company</label>
<%= builder.text_field :name, type: "text" %>
<%end%>
</div>
<div class="form-item">
<%= form.label :password %>
<%= form.password_field :password %>
</div>
I can perfectly submit my form, but my company_id is nil when finding the user object in rails console.
Anyone have an idea what I am doing wrong?
Thanks in advance!
You need to use the singular:
= form.fields_for :company
and in your controller:
company_attributes # instead of companies_attributes
and you have one thing in the wrong model! You want to save a company with the user so you need to move accepts_nested_attributes_for to user.rb
accepts_nested_attributes_for :company
I am completely unsure where i am going wrong and it surprises me that i can not figure it out, so any advise would be much appreciated.
i have 2 models userr(recruiters) & feedbackr(recruiters feedback)
[userr model] userr has_many :feedbackr
[feedbackr model] belongs_to :userr
[schema] i have added userr_id column to the table feedbackrs
[feedbackrs_controller] i have added :userr_id to the feedbackr_params
the problem is, when i create a feedback comment as a recruiter & go
into my console and type Feebackr.find(4) (the last created
feedback) the userr_id shows nil - it
is suppose to display the id of the userr(recruiter) that created a
feedback - i am unsure why it is displaying nil as my associations all seem right -
any advise would be much appreciated - i have my files below -
console
2.1.2 :055 > ap Feedbackr.find(4)
Feedbackr Load (0.3ms) SELECT "feedbackrs".* FROM "feedbackrs" WHERE "feedbackrs"."id" = ? LIMIT 1 [["id", 4]]
#<Feedbackr:0x007fd89136e018> {
:id => 4,
:email => "richill#gmail.com",
:created_at => Sun, 28 Jun 2015 00:29:52 UTC +00:00,
:updated_at => Sun, 28 Jun 2015 00:29:52 UTC +00:00,
:category_feedbackr_id => 6,
:content => "feedback1",
:userr_id => nil
}
=> nil
2.1.2 :056 >
schema
ActiveRecord::Schema.define(version: 20150627235330) do
create_table "feedbackrs", force: true do |t|
t.string "email"
t.datetime "created_at"
t.datetime "updated_at"
t.integer "category_feedbackr_id"
t.text "content"
t.integer "userr_id"
end
create_table "userrs", force: true do |t|
t.string "email", default: "", null: false
t.string "encrypted_password", default: "", null: false
t.string "reset_password_token"
t.datetime "reset_password_sent_at"
t.datetime "remember_created_at"
t.integer "sign_in_count", default: 0, null: false
t.datetime "current_sign_in_at"
t.datetime "last_sign_in_at"
t.string "current_sign_in_ip"
t.string "last_sign_in_ip"
t.datetime "created_at"
t.datetime "updated_at"
t.string "confirmation_token"
t.datetime "confirmed_at"
t.datetime "confirmation_sent_at"
t.string "unconfirmed_email"
end
add_index "userrs", ["confirmation_token"], name: "index_userrs_on_confirmation_token", unique: true
add_index "userrs", ["email"], name: "index_userrs_on_email", unique: true
add_index "userrs", ["reset_password_token"], name: "index_userrs_on_reset_password_token", unique: true
end
feedbackr.rb
class Feedbackr < ActiveRecord::Base
belongs_to :userr
end
userr.rb
class Userr < ActiveRecord::Base
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable, :confirmable
has_many :feedbackrs
end
feedbackr_controller.rb
class FeedbackrsController < ApplicationController
respond_to :html, :xml, :json
before_action :set_feedbackr, only: [:show, :edit, :update, :destroy]
def index
#feedbackrs = Feedbackr.all.order("created_at DESC")
respond_with(#feedbackrs)
end
def show
respond_with(#feedbackr)
end
def new
#feedbackr = Feedbackr.new
respond_with(#feedbackr)
end
def edit
end
def create
#feedbackr = Feedbackr.new(feedbackr_params)
respond_to do |format|
if #feedbackr.save
format.html { redirect_to dashboard_path, :notice => 'Thank you for your feedback' }
format.xml { render :xml => #feedbackr, :status => :created, :location => [#feedbackr] }
else
format.html { render :action => "new" }
format.xml { render :xml => #feedbackr.errors, :status => :unprocessable_entity }
end
end
end
def update
...
end
def destroy
...
end
private
def set_feedbackr
#feedbackr = Feedbackr.find(params[:id])
end
def feedbackr_params
params.require(:feedbackr).permit(:email, :category_feedbackr_id, :content, :userr_id)
end
end
views/feedbackrs/_form.html.erb
<%= simple_form_for(#feedbackr) do |f| %>
<%= f.error_notification %>
<div class="form-inputs">
<%= f.input_field :email, label: 'email address', value: current_userr.email %>
<%= f.association :category_feedbackr, as: :radio_buttons, label: 'How likely are you to recommend us?' %>
<%= f.input :content, label: 'What is the primary reason for your score?'%>
</div>
<div class="form-actions">
<%= f.button :submit, 'Provide Feedback' %>
</div>
<% end %>
<div><%= render 'shared/footer' %></div>
Did you want to set the current_user as the userr ?
def create
#feedbackr = Feedbackr.new(feedbackr_params)
#feedbackr.userr = current_user # And make sure the user is authenticated (though you probably did that in your ApplicationController ?)
respond_to do |format|
if #feedbackr.save
format.html { redirect_to dashboard_path, :notice => 'Thank you for your feedback' }
format.xml { render :xml => #feedbackr, :status => :created, :location => [#feedbackr] }
else
format.html { render :action => "new" }
format.xml { render :xml => #feedbackr.errors, :status => :unprocessable_entity }
end
end
end
Assigning #feedbackr.userr = current_user in your feedbackrs_controller.rb file would automatically generate the user_id field. Since currently, you didn't assign anything to user_id when feebackr is being generated, therefore your userr_id = nil.
Please help me to solve this error.When update action is executing this error is showing.
Error:
NoMethodError in UsersController#update
undefined method `permit' for :user:Symbol
My code snippets are given below.
views/users/edit.html.erb
<h1>Edit your data</h1>
<%= form_for #user,:url => {:action => 'update',:id => params[:id]} do |f| %>
<% if #user.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#user.errors.count, "error") %> prohibited this post from being saved:</h2>
<ul>
<% #user.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<%= f.text_field:name,:value => #edit.name %>
<%= f.email_field:email,:value => #edit.email %>
<%= f.text_field:message,:value => #edit.message %>
<%= f.submit "Update" %>
<% end %>
<%= link_to "Back",users_index_path %>
controller/users_controller.rb
class UsersController < ApplicationController
def index
end
def new
#user=User.new
end
def create
#user=User.new(users_params)
if #user.save
flash[:notice]="Your data is saved succesfully"
flash[:color]="valid"
redirect_to :action => 'index'
else
flash[:alert]="You are entering wrong data"
flash[:color]="invalid"
render :new
end
end
def show
#user=User.all
end
def delete
#user=User.find(params[:id])
if #user.delete
flash[:notice]=#user.name+"has deleted successfully"
flash[:color]="valid"
redirect_to :action => 'index'
else
flash[:alert]=#user.name+"could not delete.Please check it.."
flash[:color]="invalid"
render :show
end
end
def edit
#edit=User.find(params[:id])
#user=User.new
end
def update
#user=User.find(params[:id])
if #user.update_attributes(update_params)
flash[:notice]="Your data has updated successfully"
flash[:color]="valid"
redirect_to :action => 'index'
else
flash[:alert]="Your data could not update..check it.."
flash[:color]="invalid"
render :edit
end
end
private
def users_params
params.require(:user).permit(:name, :email, :message,pets_attributes: [:name, :email,:message])
end
def update_params
params.require (:user).permit(:name,:email,:message,pets_attributes: [:name, :email,:message])
end
end
model/user.rb
class User < ActiveRecord::Base
has_many :pets
accepts_nested_attributes_for :pets
EMAIL_REGEX = /\A[A-Z0-9._%+-]+#[A-Z0-9.-]+\.[A-Z]{2,4}\z/i
validates :name, :presence => true,:length => { :minimum => 5 }
validates :email, :presence => true, :uniqueness => true, :format => EMAIL_REGEX
validates :message, :presence => true
end
Please help me to solve the above error.
You have space between require and (:user). Your current code is equivalent to:
def update_params
params.require(:user.permit(:name,:email,:message,pets_attributes: [:name, :email,:message]))
end
As you can see now, you call permit method on :user symbol and this is direct cause of error.
It should be:
def update_params
params.require(:user).permit(:name,:email,:message,pets_attributes: [:name, :email,:message])
end
BTW having two methods that do exactly same thing is quite pointless.
Check your question:
you have a space after require and before (:user)
Try:
def update_params
params.require(:user).permit(:name,:email,:message,
pets_attributes: [:name, :email,:message])
end
For a better way, you can have just one method:
def user_params
params.require(:user).permit(:name,:email,:message,
pets_attributes: [:name, :email,:message])
end
Instead of having separate filter methods for new and edit, you can have just one method and reuse that in both new and edit.
Just keep things Simply DRY.
I am having trouble figuring out how to list all of the USERS who have LIKED a particular POST. Currently I am using:
<span class="count"><%= dailypost.likes.count %></span>
This has allowed me to count all of the LIKES associated with that particular POST.BUT it does not list the actual users.
I have tried using this to list all of the USERS who LIKED that POST
<%= dailypost.likes %>
Instead I get back:
[#<Like id: 360, dailypost_id: 306, user_id: 1, created_at: "2013-04-28 21:51:45", updated_at: "2013-04-28 21:51:45">,
#<Like id: 319, dailypost_id: 306, user_id: 104, created_at: "2013-04-28 19:27:35", updated_at: "2013-04-28 19:27:35">,
#<Like id: 314, dailypost_id: 306, user_id: 103, created_at: "2013-04-28 19:24:19", updated_at: "2013-04-28 19:24:19">]
DOES ANYONE KNOW HOW I CAN PULL THE LIST OF USERS OR USER_ID'S??
New to RAILS please help!!
MODELS
class User < ActiveRecord::Base
has_many :likes, dependent: :destroy
has_many :dailyposts, dependent: :destroy
end
class Dailypost < ActiveRecord::Base
belongs_to :user
has_many :likes
end
class Like < ActiveRecord::Base
belongs_to :user
belongs_to :dailypost
end
DATABASE
ActiveRecord::Schema.define(:version => 20130210095553) do
create_table "dailyposts", :force => true do |t|
t.string "content"
t.integer "user_id"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
create_table "likes", :force => true do |t|
t.integer "dailypost_id"
t.integer "user_id"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
create_table "users", :force => true do |t|
t.string "name"
t.string "email"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
end
VIEWS
<span class="count"><%= dailypost.likes.count %></span>
<%= dailypost.likes %>
<span class="like">
<% if like = current_user.likes.find_by_dailypost_id(dailypost.id) %>
<%= form_for like, :html => { :method => :delete }, remote: true do |f| %>
<span title="Unlike!"><%= image_submit_tag "Superman1.png" %></span>
<% end %>
<% else %>
<%= form_for current_user.likes.build, remote: true do |f| %>
<div><%= f.hidden_field :dailypost_id, value: dailypost.id %></div>
<%= f.hidden_field :user_id %>
<span title="Like!"><%= image_submit_tag "Superman2.png" %></span>
<% end %>
<% end %>
</span>
The simplest way to understand is to take each like, and ask it for its user:
dailypost.likes.map {|l| l.user}
Of course that does a database lookup for each like, which you may wish to avoid if you have hundreds and hundreds of users.
So a more sophisticated way is to do a single query to get all the users by user_id:
User.find(dailypost.likes.map {|l| l.user_id})
This will give you a list of users, and it's up to you what you do with it. If you just want a HTML list, try this instead:
<ul>
<% dailypost.likes.each do |l| %>
<li> <%= link_to(l.user.name, l.user) %></li>
<% end %>
</ul>
This looks at each like in turn, and then asks it for its user, and then asks the user for its name.