I am new to the rails community. I am working on an application where users can have username with a nested attribute of first and last name. The other text field associated with the User model works fine.
Any help would be much appreciated.
Attached are the app models, controllers, migration files, db schema, and views.
models
class User < ActiveRecord::Base
has_one :username, dependent: :destroy
accepts_nested_attributes_for :username, allow_destroy: true
end
class Username < ActiveRecord::Base
belongs_to :user
end
Migrations
class CreateUsers < ActiveRecord::Migration
def change
create_table :users do |t|
t.string :email
t.string :about_me
t.string :nationality
t.string :sexe
t.timestamps null: false
end
end
end
class CreateUsernames < ActiveRecord::Migration
def change
create_table :usernames do |t|
add_column :username, :first_name, :string
add_column :username, :last_name, :string
t.references :user, index: true, foreign_key: true
t.timestamps null: false
end
end
end
controller
class UsersController < ApplicationController
def index
#all_users = User.all
#new_user = User.new
#username = Username.new
end
def new
#new_user = User.new
end
def create
User.create(user_params)
end
private
def user_params
params.require(:user).permit(:email, :about_me, username_attributes:
[:last_name, :first_name])
end
end
Views
<h1>Users#index</h1>
<p>Find me in app/views/users/index.html.erb</p>
<%= form_for #new_user do |f| %>
<%= f.fields_for #new_user do |user| %>
<div class="field">
<%= user.label :email%>
<%= user.text_field :email %>
<%= user.label :about_me %>
<%= user.text_field :about_me %>
</div>
<% end %>
<%= f.fields_for :username do |name| %>
<div class="field">
<%= name.label :first_name %>
<%= name.text_field :first_name %>
</div>
<% end %>
<div class="form-actions">
<%= f.button :submit %>
</div>
<% end %>
Try this
controller
def new
#new_user = User.new
#new_user.usernames.build
end
view
<%= form_for #new_user do |f| %>
# ...
<%= f.fields_for :usernames do |name| %>
<div class="field">
<%= name.label :first_name %>
<%= name.text_field :first_name %>
</div>
<% end %>
# ...
<% end %>
helper
def name_format(user_mst)
name = user_mst.first_name.capitalize
name += (" #{user_mst.last_name.capitalize}")
return name
end
to display on view
Related
I have devise up and running and everything is work fine, I'm trying to accept_nested_attributes for the user model. I generated a model called degree:
rails g model Degree university:string course:string level:string user:references
rake db:migrate
The form is showing correct but no data is getting saved to the database? in the rails console i ran:
Degree.all
to see if any data is being saved but i get nothing?
registration_controller.rb:
class Users::RegistrationsController < Devise::RegistrationsController
before_filter :configure_permitted_parameters, if: :devise_controller?
protected
def configure_permitted_parameters
devise_parameter_sanitizer.for(:sign_up) { |u| u.permit(:email, :password, :password_confirmation,
:fname, :mname, :lname, :twitterLink, :githubLink, :stackoverflowLink, :dribbleLink, :mediumLink, degree_attributes: [:university, :course, :level]) }
#devise_parameter_sanitizer.for(:account_update) { |u| u.permit(:fname, :mname, :password, :current_password, :lname) }
end
end
Models
class Degree < ActiveRecord::Base
belongs_to :user
end
----------------------------------
class User < ActiveRecord::Base
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
has_many :degrees
accepts_nested_attributes_for :degrees
end
form where nested attributes are:
<h2>Sign up</h2>
<% resource.degrees.build %>
<%= form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %>
<%= devise_error_messages! %>
<div class="field">
<%= f.label :email %><br />
<%= f.email_field :email, autofocus: true %>
</div>
<div class="field">
<%= f.label :password %>
<% if #minimum_password_length %>
<em>(<%= #minimum_password_length %> characters minimum)</em>
<% end %><br />
<%= f.password_field :password, autocomplete: "off" %>
</div>
<div class="field">
<%= f.label :password_confirmation %><br />
<%= f.password_field :password_confirmation, autocomplete: "off" %>
</div>
<div class="field">
<%= f.fields_for :degree do |degree_fields| %>
<%= degree_fields.label :university %>
<%= degree_fields.text_field :university %><br>
<%= degree_fields.label :course %>
<%= degree_fields.text_field :course %><br>
<%= degree_fields.label :level %>
<%= degree_fields.text_field :level %><br>
<% end %>
</div>
<div class="actions">
<%= f.submit "Sign up" %>
</div>
<% end %>
degree_controller.rb
class DegreeController < ApplicationController
def new
#user = User.new
#user.degrees.build(degree_params)
end
def create
#user.degrees.build(degree_params)
end
private
def degree_params
params.require(:degree).permit(:university, :degree, :level)
end
end
I would like with Rails4 to assign the current_user.email to a comment.
This comment is assign to a book.
[Page book][1] [1]: http://i.stack.imgur.com/2mEoG.png
I succeed to assign the current_user.email to a comment
but when i try to change the current_user with an other account, all the email of the comments change also. And i don't want that!
How can i resolve the problem?
Here some files of my app:
CommentsController:
class CommentsController < ApplicationController
def create
#book = Book.find(params[:book_id])
#comment = #book.comments.new(comment_params)
if #comment.save
redirect_to #comment.book, notice: I18n.t('books.comment')
else
render text: 'Error!'
end
end
private
def comment_params
params.require(:comment).permit(:message)
end
end
view:
<% if comment.message != nil %>
<li><strong><%= current_user.email %></strong></li>
<p><%= comment.message %></p>
<% end %>
form_for:
<%= form_for [#book, #comment] do |f| %>
<%= f.hidden_field :book_id %>
<%= f.text_area :message, :placeholder => "Message" %>
<br />
<%= f.submit %>
<% end %>
Table Comments:
class CreateComments < ActiveRecord::Migration
def change
create_table :comments do |t|
t.text :message
t.string :username
t.integer :book_id
t.integer :reader_id
t.integer :user_id
t.timestamps
end
end
end
Table Readers:
class CreateReaders < ActiveRecord::Migration
def change
create_table :readers do |t|
t.string :name
t.string :email
t.timestamps
end
end
end
Table Books:
class CreateBooks < ActiveRecord::Migration
def change
create_table :books do |t|
t.string :title
t.string :author
t.string :synopsis
t.timestamps
end
end
end
Well, if you want have assigned current user to comment you can place a hidden field to save users id (make sure you have configured associations in models):
form_for:
<%= form_for [#book, #comment] do |f| %>
...
<%= f.hidden_field :user_id, value: current_user.id %>
...
<% end %>
Update comment_params in controller:
private
def comment_params
params.require(:comment).permit(:message, :user_id)
end
and then, in view:
<% if comment.message != nil %>
<li>
<strong>
<%= comment.user.email %>
</strong>
</li>
<p><%= comment.message %></p>
<% end %>
That's it. If you need use reader model instead of user - you can do it in the same way..
I am new to ruby on rails and coding in general.
I wrote a nested form_for where the Price class belongs to an Item class.
The values :amount, :timeframe, and :item_id are to be stored through the controller. After the action ends only the :timeframe and :item_id are stored but not the :amount value.
Does this have to do with:
The nested form?
The datatype, and or precision & scale details for :amount?
Could it also be an issue with my controller method?
Any clarification would be greatly appreciated!
Here is the form:
<%= form_for #item, html: {multipart: true} do |f| %>
<div class="main-form">
<div class="new-item-form">
<%= f.label :title %>
<%= f.text_field :title %>
</div>
<div class="new-item-form">
<%= f.label :description %>
<%= f.text_field :description %>
</div>
<div class="new-item-form">
<%= f.label :deposit %>
<%= f.text_field :deposit %>
</div>
<div class="new-item-form">
<%= f.label :tags %>
<%= f.text_field :tags %>
</div>
<div class="new-item-form">
<%= f.label :image %>
<%= f.file_field :image %>
</div>
<%= fields_for :price do |f| %>
<div class="new-item-form">
<%=f.label :timeframe %>
<%= select_tag(:timeframe, options_for_select([["Hour"],["Day"],["Week"]])) %>
</div>
<div class="new-item-form">
<%=f.label :amount %>
<%=f.number_field :amount %>
</div>
<% end %>
<%= f.submit %>
<%end%>
This is the controller:
class ItemsController < ApplicationController
def show
#item = Item.find(params[:id])
#price = Price.where(item_id: #item.id).first
end
def new
#item = Item.new
end
def create
#item = Item.new(item_params)
if #item.save
#price = Price.create(:timeframe => params[:timeframe], :amount => params[:amount], :item_id => #item.id)
#price.save
redirect_to #item, notice: "Item Successfully Added!"
else
flash[:message] = "Something did not validate"
render 'new'
end
end
private
def item_params
params.require(:item).permit(:title, :description, :image, :user_id, :deposit, :tags)
end
end
Additional documents include the Item model and Price model:
class Item < ActiveRecord::Base
validates :title, :description, :deposit, :tags, presence: true
belongs_to :user
has_many :prices, :dependent => :destroy
has_many :reviews, :dependent => :destroy
has_many :ratings, :dependent => :destroy
has_many :users_that_reviewed_this, through: :reviews, source: :user
has_many :users_that_rated_this, through: :ratings, source: :user
end
class Price < ActiveRecord::Base
belongs_to :item end
As well as the database schema for these classes:
create_table "items", force: :cascade do |t|
t.string "title"
t.string "description"
t.string "image"
t.integer "user_id"
t.integer "deposit"
t.string "type"
t.string "tags"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "prices", force: :cascade do |t|
t.string "timeframe"
t.decimal "amount"
t.integer "item_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
The problem in your code is in params[:amount]. No params are there, it should be params[:price][:amount]. It will work this way!
Though the approach is not the most "conventional"
Here is the correct approach using accepts_nested_attributes, adding prices_attributes to strong_parameters and using
In your model
class Item < ActiveRecord::Base
validates :title, :description, :deposit, :tags, presence: true
belongs_to :user
has_many :prices, dependent: :destroy
has_many :reviews, dependent: :destroy
has_many :ratings, dependent: :destroy
has_many :users_that_reviewed_this, through: :reviews, source: :user
has_many :users_that_rated_this, through: :ratings, source: :user
accepts_nested_attributes_for :prices, reject_if: :all_blank, allow_destroy: true
end
In your controller
def create
#item = Item.new(item_params)
#item.prices.build
if #item.save
redirect_to #item, notice: "Item Successfully Added!"
else
flash[:message] = "Something did not validate"
render 'new'
end
end
private
def item_params
params.require(:item).permit(:title, :description, :image, :user_id, :deposit, :tags, prices_attributes: [:timeframe, :amount])
end
In your view
<%= form_for #item, html: {multipart: true} do |f| %>
<div class="main-form">
<div class="new-item-form">
<%= f.label :title %>
<%= f.text_field :title %>
</div>
<div class="new-item-form">
<%= f.label :description %>
<%= f.text_field :description %>
</div>
<div class="new-item-form">
<%= f.label :deposit %>
<%= f.text_field :deposit %>
</div>
<div class="new-item-form">
<%= f.label :tags %>
<%= f.text_field :tags %>
</div>
<div class="new-item-form">
<%= f.label :image %>
<%= f.file_field :image %>
</div>
<%= f.fields_for :prices, Price.new do |p| %>
<div class="new-item-form">
<%=p.label :timeframe %>
<%= p.select(:timeframe, [["Hour"],["Day"],["Week"]], :prompt => 'Select') %>
</div>
<div class="new-item-form">
<%=p.label :amount %>
<%=p.number_field :amount %>
</div>
<% end %>
<%= f.submit %>
<%end%>
I have two models with a one to one relationship, User and Author.
I have two issues: the author instance isn't saving, and user.name isn't saving (although other attributes are). I think it is a permission error because the logs say:
Unpermitted parameters: name, authors
I was trying to follow this: How to save form data to different models with one-to-one relationship in rails 3?
User.rb
has_one :author
accepts_nested_attributes_for :author
Author.rb
belongs_to :user
authors#new
<%= simple_form_for #user do |f| %>
<%= f.input :name %>
<%= f.input :email %>
<%= f.input :password %>
<%= f.input :password_confirmation %>
<%= f.simple_fields_for :author do |author_form| %>
<%= author_form.input :bio %>
<% end %>
<%= f.submit %>
<% end %>
Users_Controller
def user_params
params.require(:user).permit(:name, :email, :image,
author_attributes: [:id, :bio,])
end
User controller should look like this:-
def new
#user = User.new
#user.build_author
end
def create
#user = User.new(user_params)
if #user.save
redirect_to success_path
else
render :new
end
end
private
def user_params
params.require(:user).permit(:name, :email, :password, :password_confirmation, author_attributes: [:id, :bio])
end
Users#new
<%= simple_form_for #user do |f| %>
<%= f.input :name %>
<%= f.input :email %>
<%= f.input :password %>
<%= f.input :password_confirmation %>
<%= f.simple_fields_for :author do |author_form| %>
<%= author_form.input :bio %>
<% end %>
<%= f.submit %>
<% end %>
I'm using the Devise gem and found the solution to be adding this code to the Application Controller:
before_action :configure_permitted_parameters, if: :devise_controller?
def configure_permitted_parameters
devise_parameter_sanitizer.for(:sign_up) { |u| u.permit(:name, :email, :password, author_attributes: [:id, :bio]) }
end
I used associations in the models whenever I am applying associations I am getting problem ,I am new to ruby as well as rails.I am using Rails4,Eclipse,Windows Xp(sp3) and mysql5.6 ,I am getting the above error when I want clicked the show link the error is
undefined method `post_comments_path' for #<#<Class:0x2aef820>:0x2bd7df8>
Extracted source (around line #25):
<h2>Add a comment:</h2>
<%= form_for([#post, #post.comments.build]) do |f| %>...here it is line number 25
<p>
<%= f.label :commenter %><br />
<%= f.text_field :commenter %>
I have two model
post.rb
class Post < ActiveRecord::Base
has_many :comments
validates :title, presence: true,
length: { minimum: 5 }
end
comment.rb
class Comment < ActiveRecord::Base
belongs_to :post
end
I have two controllers
posts_controller.rb
class PostsController < ApplicationController
def new
#post=Post.new
end
def show
#post = Post.find(params[:id])
end
def edit
#post = Post.find(params[:id])
end
def update
#post = Post.find(params[:id])
if #post.update(params[:post].permit(:title, :text))
redirect_to #post
else
render 'edit'
end
end
def destroy
#post = Post.find(params[:id])
#post.destroy
redirect_to posts_path
end
def create
#post = Post.new(post_params)
# it will also works #post=Post.new(params[:post].permit(:title,:text))
if #post.save
redirect_to #post
# or this command also works redirect_to action: :show, id: #post.id
else
render 'new'
end
end
def index
#posts = Post.all
end
private
def post_params
params.require(:post).permit(:title, :text)
end
end
comments_controller.rb
class CommentsController < ApplicationController
def create
#post = Post.find(params[:post_id])
#comment = #post.comments.create(params[:comment].permit(:commenter, :body))
redirect_to post_path(#post)
end
end
my routes.rb file is
Blog::Application.routes.draw do
resources :posts do
resources :comments
end
I have two migration files
create_posts.rb
class CreatePosts < ActiveRecord::Migration
def change
create_table :posts do |t|
t.string :title
t.text :text
t.timestamps
end
end
end
create_comments.rb
class CreateComments < ActiveRecord::Migration
def change
create_table :comments do |t|
t.string :commenter
t.text :body
t.references :post
#above line sets foreign key column for the association between the two models.
t.timestamps
end
#and bellow add_index line sets up an index for this association column.
add_index :comments, :post_id
end
end
my show.html.erb file is
<p>
<strong>Title:</strong>
<%= #post.title %>
</p>
<p>
<strong>Text:</strong>
<%= #post.text %>
</p>
<h2>Comments</h2>
<% #post.comments.each do |comment| %>
<p>
<strong>Commenter:</strong>
<%= comment.commenter %>
</p>
<p>
<strong>Comment:</strong>
<%= comment.body %>
</p>
<% end %>
<h2>Add a comment:</h2>
<%= form_for([#post, #post.comments.build]) do |f| %>
<p>
<%= f.label :commenter %><br />
<%= f.text_field :commenter %>
</p>
<p>
<%= f.label :body %><br />
<%= f.text_area :body %>
</p>
<p>
<%= f.submit %>
</p>
<% end %>
<%= link_to 'Edit Post', edit_post_path(#post) %> |
<%= link_to 'Back to Posts', posts_path %>
I used associations in the models whenever I am applying associations I am getting problem ,I am new to ruby as well as rails.I am using Rails4,Eclipse,Windows Xp(sp3) and mysql5.6 ,I am getting the above error when I want clicked the show link the error is I used associations in the models whenever I am applying associations I am getting problem ,I am new to ruby as well as rails.I am using Rails4,Eclipse,Windows Xp(sp3) and mysql5.6 ,I am getting the above error when I want clicked the show link the error is
I have a feeling you missed the part about nested resources. As in:
resources :posts do
resources :comments
end
This means the routes generated by resources :comments are nested within your posts, which results in URLs like this:
/posts/1/comments