Rails - Nested Strong parameters - ruby-on-rails

I'm trying to create an user register using two models User and profile, nested strong parameters in one controller. when I send parameter I get this error unknown attribute 'profiles_attributes' for User. and I can't create user neither profile :
class User < ActiveRecord::Base
has_one :profile
has_many :apartments
has_many :session
has_secure_password
validates :email, presence: true, uniqueness: true
validates :password, presence: true
accepts_nested_attributes_for :profile
end
class Profile < ActiveRecord::Base
belongs_to :user
belongs_to :city
has_many :profile_universities
has_many :universities, through: :profile_universities
has_many :profile_preferences
has_many :preferences, through: :profile_preferences
has_one :photo, :as => :imageable
end
class Api::V1::UserController < ApplicationController
before_action :user_params
def create_without_facebook
#user= User.new(user_params)
if #user.save
#profile = Profile.new(user_params[:profiles_attributes])
render json: [#user, #profile]
else
render json: #user.errors, status: :unprocessable_entity
end
end
def user_params
params.require(:user).permit(:email, :password, profiles_attributes: [:first_name, :last_name, :birthday, :gender, :marital_status, :ocupation, :budget, :question, :about, :city])
end
end

use the singular profile_attributes if it's a has_one

Related

Rails NoMethodError: undefined method `includes' for #<User:0x007f62dbbe62f8>

I'm using the active_model_serializers gem in my Rails 5 app. I created a few serializer files in /app/seralizers, user_serializer.rb, sector_serializer.rb, and slot_serializer.rb .
class UserSerializer < ActiveModel::Serializer
attributes :id, :first_name, :last_name, :email, :phone, :admin, :auth_token, :organization_id
has_many :sectors
has_many :slots
has_many :elements
end
class SectorSerializer < ActiveModel::Serializer
attributes :id, :user_id, :sector_number, :title
belongs_to :user
has_many :slots
has_many :elements
end
class SlotSerializer < ActiveModel::Serializer
attributes :id, :user_id, :sector_id, :sector_number, :title, :slot_number
belongs_to :user
belongs_to :sector
has_many :elements
end
And in my controller code, I have:
class Api::V1::UsersController < API::V1::BaseController
respond_to :json
def sky
#user = User.find_by_id(params[:user_id]).includes(:sectors, :slots)
if #user
render json: #user
else
raise "Unable to get Sky"
end
end
end
My server is throwing an error at the line where I do the .includes and I can't figure out why.
Any help is appreciated. Thanks!
Change
#user = User.find_by_id(params[:user_id]).includes(:sectors, :slots)
to
#user = User.includes(:sectors, :slots).find_by_id(params[:user_id])
Point is you have to call includes on a class (that inherits from ActiveRecord::Base/ApplicationRecord), not a single user object.

how to show 'recently visited'?

I have created a web app that has user profiles, where users can search for fellow users based on interests, as well as post + attend events etc.. How might I add a feature where users can see who 'Recently visited' a certain event?
event.rb
class Event < ActiveRecord::Base
attr_accessible :title, :description, :location, :date, :time, :event_date
acts_as_commentable
has_many :comments, as: :commentable
belongs_to :user
has_many :event_participants, dependent: :destroy
has_many :participants, through: :event_participants, source: :user
end
user.rb
class User < ActiveRecord::Base
include PgSearch
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable, :omniauthable,
:omniauth_providers => [:facebook, :twitter, :linkedin]
attr_accessible :email, :password, :password_confirmation, :zip, :gender, :remember_me, :first_name, :last_name,
:birthday, :current_password, :occupation, :address, :interests, :aboutme, :profile_image,
:photos_attributes, :age, :education, :ethnicity
has_many :authorizations, :dependent => :destroy
has_many :comments
has_many :events
has_many :photos, as: :attachable
has_many :questions
has_many :sent_messages, class_name: 'Message', foreign_key: :sender_id
has_many :received_messages, class_name: 'Message', foreign_key: :receiver_id
accepts_nested_attributes_for :photos
mount_uploader :profile_image, ProfileImageUploader
end
event_participants.rb
class EventParticipant < ActiveRecord::Base
attr_accessible :user_id, :event_id
belongs_to :user
belongs_to :event
validates :user_id, uniqueness: {scope: :event_id}
end
events_controller snippit
class EventsController < ApplicationController
before_filter :authenticate_user!
def index
#users = User.all
#user = current_user
#events = Event.all
#interesting_people = #users.order("random()").first(5)
end
def new
#event = Event.new
end
def create
#event = current_user.events.new(event_params)
respond_to do |format|
if #event.save
format.html { redirect_to :back, notice: 'Event was successfully created.' }
format.json { render action: 'show', status: :created, location: #event }
format.js
else
format.html { render action: 'new' }
format.json { render json: #event.errors, status: :unprocessable_entity }
format.js
end
end
end
def show
#users = User.all
#user = current_user
#event = Event.find(params[:id])
#commentable = #event
#comment = #event.comments.new
#interesting_people = #users.order("random()").first(5)
end
Based on your code, it looks like you could do something like:
#event.event_participants.include(:users).order('created_at desc').limit(X).map(&:user)
You could also try without the include:
#event.event_participants.order('created_at desc').limit(X).map(&:user)
But that will do N+1 queries. The join will perform better.
Where in the above code, X would be how many participants you want to show.

Can't mass-assign protected attributes:

Have tried the solutions for this common error in stackoverflow but none of them seem to work in this case, it might be that I already created an address field on the property before. I keep getting the mass assignment error.
Any help appreciated.
Address.rb
class Address < ActiveRecord::Base
attr_accessible :addressable_id, :addressable_type, :city, :county, :postcode, :street1, :street2
belongs_to :addressable, :polymorphic => true
end
Property.rb
class Property < ActiveRecord::Base
attr_accessible :name, :addresses_attributes
belongs_to :user
has_one :address, :as => :addressable
accepts_nested_attributes_for :address
validates :name, presence: true, length: { maximum: 200 }
validates :address, presence: true
validates :user_id, presence: true
end
Property Controller
class PropertiesController < ApplicationController
before_filter :authenticate_user!
before_filter :correct_user, only: :destroy
def index
#property= Property.all
end
def create
#property = current_user.properties.build(params[:property])
if #property.save
flash[:success] = " Property Added"
redirect_to root_path
else
render 'edit'
end
end
def new
#property = Property.new
#property.build_address
end
You should add
accepts_nested_attributes_for :address
and change
attr_accessible :name, :address_attributes
and if it doesn't work change both address to addressable

Stack level too deep: creating child-record

My problem: User has_one Profile. When new User is created, APP also automatically creates Profile, which belongs to User. I tried to do it through controller, through callback, always same error (Stack level too deep). My models:
class User < ActiveRecord::Base
has_secure_password
attr_accessible :email, :password, :password_confirmation
validates_uniqueness_of :email, :case_sensitive => false
validates :email, :email_format => true
validates :password, :length=> {:in=> 5...32}
validates :email, :password, :password_confirmation, :presence =>true
has_many :authentications
has_many :tests
has_many :answers
has_many :results
has_one :profile
#after_create :build_profile
#tried this way
def build_profile
self.build_profile
end
end
#
class Profile < ActiveRecord::Base
attr_accessible :user_id
belongs_to :user
end
#
def create
#user = User.new(params[:user])
#user.email=#user.email.downcase
if #user.save
session[:user_id] = #user.id
#profile=#user.build_profile
redirect_to root_url, notice: "Thank you for signing up!"
else
render "new"
end
end
Alsways same error. Why?
def build_profile
self.build_profile
end
This loops endlessly (and I can't see the point, what did you want to do?)
you should simply remove the build_profile method (don't worry, it's defined thanks to the association).
user = User.new
user.build_profile
|_ calls self.build_profile, but self is user
|_ calls user.build_profile
|_ ...

Has a relationship through four models?

I'm having trouble setting up this association between my models.
A User has many Accommodations, and Accommodations have one User.
Accommodations have many Notifications, and Notifications have one Accommodation.
Requests have many Notifications.
How can I make it so that I can get all of the Requests for a given User ( that is, User -> Accommodations (each) -> Notification -> Request)?
Update:
Here's my current controller file:
class PanelController < ApplicationController
before_filter :login_required
def index
#accommodations = current_user.accommodations.all
#requests = Array.new
#accommodations.each do |a|
a.notifications.each do |n|
#requests << Request.where('id' => n.request_id)
end
end
end
end
And models:
models/user.rb
class User < ActiveRecord::Base
[snip]
has_many :accommodations
has_many :notifications,
:through => :accommodations
end
models/accommodation.rb
class Accommodation < ActiveRecord::Base
validates_presence_of :title, :description, :thing, :location, :spaces, :price, :photo
attr_accessible :photo_attributes, :title, :description, :thing, :location, :spaces, :price
has_one :photo
has_many :notifications
belongs_to :user
accepts_nested_attributes_for :photo, :allow_destroy => true
end
models/notification.rb
class Notification < ActiveRecord::Base
attr_accessible :accommodation_id, :request_id
has_one :request
belongs_to :accommodation
end
models/request.rb
class Request < ActiveRecord::Base
belongs_to :notifications
attr_accessible :firstname, :lastname, :email, :phone, :datestart, :dateend, :adults, :children, :location, :status
validates_presence_of :firstname, :lastname, :email, :phone, :datestart, :dateend, :children, :adults, :location
end
Something like this should work:
#reqs = []
#user.accommodations.all.each do |a|
#reqs << a.notification.request
end
Assuming this is correct:
class User
has_many :accommodations
end
class Accommodation
belongs_to :user
has_many :notifications
end
class Notification
belongs_to :accomodation
belongs_to :request
end
class Request
has_many :notifications
end
Using has_many :through will not work for multiple models, as seen here: Ruby-on-Rails: Multiple has_many :through possible?
But you can do something like this in your user model:
class User
has_many :accommodations
has_many :notifications,
:through => :accommodations
def requests
self.notifications.all.collect{|n| n.request }
end
end

Resources