Undefined Method in Picture Controller - methods

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

Where to permit a parameter in a has_one/belongs_to association?

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 %>

Multi model sign up with clearance in Rails 4

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

Rails Associations - user_id states nil Rails 4

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.

How to solve undefined method `permit' for :user:Symbol error in ror-4

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.

How to list the users who LIKE a given Post

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.

Resources