I have a user that has_one :company. I need to build the company's attributes via the strong parameters, but i'm running into a ActiveModel::ForbiddenAttributesError. My code looks like this:
def create
#user = User.new(permitted_user_params)
#user.build_company(params[:user][:company_attributes])
end
def permitted_user_params
params.require(:user).permit(:email, :first_name, :last_name,
company_attributes: [:name, :bio])
end
My company.rb looks like
class Company < ActiveRecord::Base
belongs_to :user
end
My user.rb
class User < ActiveRecord::Base
has_one :company
accepts_nested_attributes_for :company
end
Any help is appreciated, thanks.
So you shouldn't need to do this part:
#user.build_company(params[:user][:company_attributes])
that part is implied in accepts_nested_attributes and it should do that for you, as long as you have you permit/require set up correctly (which you do).
Related
I have a relation within my application where one Client has Address which belongs to one Province.
Now I want to put the province name near the client data, so I created a method in client.rb:
def province_name
try(:address).try(:province).try(:name)
end
The problem is that not every client has joined address. This method works but it looks ugly. Is it possible to write in a better way, maybe using delegate method?
We've achieved something similar before:
#app/models/client.rb
class Client < ActiveRecord::Base
has_one :address
end
#app/models/address.rb
class Address < ActiveRecord::Base
belongs_to :province
delegate :name, to: :province
end
#app/models/province.rb
class Province < ActiveRecord::Base
has_many :addresses
def name
self[:name] ||= province
end
def province
self[:province] ||= address
end
end
You may wish to refactor the above code - but it works perfectly for us:
#app/models/user.rb
class User < ActiveRecord::Base
has_one :profile, inverse_of :user
delegate :name, to: :profile
end
#app/models/profile.rb
class Profile < ActiveRecord::Base
belongs_to :user, inverse_of :profile
def name
self[:name] ||= user.email
end
end
In my users controller i hav defined-
def user_params
params.require(:user).permit(:name,:email,:password,:password_confirmation)
end
In ticket template
Created by <%= #ticket.user.email %>
when I write ticket.user.name , it displays the name but when i write email, its invisible.
class Ticket < ActiveRecord::Base
belongs_to :project
belongs_to :user
end
class Project < ActiveRecord::Base
has_many :tickets, dependent: :destroy
validates :name, presence: true
end
I assume the email didn't get saved? Go to your Command Line, type rails c, then find that user..maybe User.first if it's the first user...tell me if that user has an email attached to it
I'm feeling a little bit dumb to ask this, but I've been Googling my a*# off.
Well I have the following models:
class Company < ActiveRecord::Base
has_many :employments
has_many :users, through: :employments
validates_presence_of :name
validates_presence_of :description
validates_numericality_of :zip, only_integer: true
validates_presence_of :email
validates_presence_of :street
validates_presence_of :city
validates_presence_of :country
validates_presence_of :telephone
end
class Employment < ActiveRecord::Base
belongs_to :user
belongs_to :company
end
class User < ActiveRecord::Base
has_many :employments
has_many :companies, through: :employments
end
Important here is the company-Model which has some validations.
Now, I have the following Controller to create a new Company:
class CompaniesController < ApplicationController
def create
#company = Company.new(company_params) # The params were set with a private Method
#employment = #company.employments.build(user: current_user, is_admin: true)
if #employment.save
redirect_to :back, flash: { success: 'Success' }
else
#title = 'Create a new company'
render :new
end
end
end
The Problem is, that when I leave the companies-Fields blank, the company gets not created, but the employment-Model gets persistet in the Database.
I believe It has something to do with the Company.new()-Call I have to check, if the #company-Model gets created first, before the #employment-Model gets created.
How can I achieve that the validation gets tested first?
Thank you very much!
To validate associated object you need to use validates_associated. Please note the "Warning" and "Note" in the linked api document.
Try:
class Employment < ActiveRecord::Base
belongs_to :user
belongs_to :company
validates_associated :company
end
in addition to vinodadhikary's answer, you can also try saving the company. so instead of #employment.save, use #company.save. That should also save #employment when #company passes validations.
I have one project for school and I am little bit confused how to make tag and category asociated posts so when I was looking for some tips in google I found this thread. So I tried scaffolding as described and it was working just fine, but when I ran the server and tried to create new post this appeared:
ActiveModel::MassAssignmentSecurity::Error in PostsController#create
Can't mass-assign protected attributes: category, user
So I really don't know what is wrong but I can use some help. Or maybe there can be suggested another way, mabe simpler how to scaffold posts with tags and categories.
Thank you very much
Here are the models:
class Post < ActiveRecord::Base
belongs_to :category
belongs_to :user
attr_accessible :body, :title, :category, :user
end
class Category < ActiveRecord::Base
attr_accessible :name
end
class Serie < ActiveRecord::Base
attr_accessible :name, :website
end
class Tag < ActiveRecord::Base
attr_accessible :name
end
class TagsSerie < ActiveRecord::Base
belongs_to :serie
belongs_to :tag
# attr_accessible :title, :body
end
class TagsPost < ActiveRecord::Base
belongs_to :post
belongs_to :tag
# attr_accessible :title, :body
end
class User < ActiveRecord::Base
attr_accessible :email, :password
end
Add attr_accessible in your post model:
class Post < ActiveRecord::Base
attr_accessible :category_id, :user_id, :other_attributes_from_post_model
end
Try setting attr_accessible :category_id, :user_id in your post model.
By default, Rails creates the scaffolded models with all its attributes non-accessible, so they are not available to edit by an external user.
So, when you tried to create a new Post, the error message raised, as category and user are protected attributes of Post.
You should review your app/models/post.rb and the rest of your models in the same folder to define as accessible those attributes that should be editable by an external user (a web user, for instance).
class Post < ActiveRecord::Base
attr_accessible :category_id, :user_id
end
On the other hand, the so accessible attributes are not protected any more for external edition so you should not use attr_accessible for all of them but just for ones that you will really allow to be modified externally.
I have a data model that looks like this:
A customer has subscription_id and setup_id as parameters. In some cases, customer will only have one of the parameters. In other cases, it will have both.
Currently, if I make a new customer through either the subscriptions flow or the setups flow, either Subscription.last or Setup.last will reflect the most recent customer that was created (with customer_id equalling the last customer created)
However, I am having the problem of Customer.setup_id or Custumer.subscription_id being nil in all cases.
Here's my code from both subscription.rb and setup.rb:
class Subscription < ActiveRecord::Base
attr_accessible :status, :customer_id
belongs_to :customer
end
class Setup < ActiveRecord::Base
attr_accessible :status, :customer_id
belongs_to :customer
end
And in customer.rb:
class Customer < ActiveRecord::Base
attr_accessible :email, :name, :stripe_token, :subscription_id, :setup_id, :phone, :plan
has_one :subscription
has_one :setup
end
I'm not sure what I'm doing incorrectly here but I'd love it if the three data models could talk to each other correctly.
Edit: Is it bad that both setup and subscription belong to :user rather than :customer?
Edit 2: Updated the code of setup.rb and subscriptions.rb to correctly reflect the data model currently. And customer.rb is still not recognizing the correct setup_id or subscription_id
class Subscription < ActiveRecord::Base
attr_accessible :status, :customer_id
belongs_to :customer
end
class Setup < ActiveRecord::Base
attr_accessible :status, :customer_id
belongs_to :customer
end
class Customer < ActiveRecord::Base
attr_accessible :email, :name, :stripe_token, :phone, :plan
has_one :subscription
has_one :setup
end
customer = Customer.first
customer.subscription # Instance of Subscription that belongs to customer
customer.setup # Instance of Setup that belongs to customer