i'm working on classified portal in which i have following 3 models
User (name,email)
Advertisement (title,body,user_id)
Bid (user_id,ad_id,price)
i have association between User and Advertisement as follow
class User < ActiveRecord::Base
has_many :advertisements
end
class Advertisement < ActiveRecord::Base
belongs_to :user
end
Now i wanna define Bid model , i guess this is how it should look like ,
class Bid < ActiveRecord::Base
belongs_to :user
belongs_to :advertisement
end
and i should add has_many :bids in User and Advertisement model as well(i think so),
Now my question is, say User is logged in and he wants to bid for some advertisement , so on advertisements show page how should i integrate this bid form, and please do let me how should i define routes for this .
Rails 3.2.13
Ruby 2.0.0p0
Thanks
Take a look at business logic of your app, there are two stories you have to implement
1) User can create advertisements (offers) (thats why you added user_id in Advertisement)
2) And user can bid on advertisements (thats simple has_many :through association)
class User < ActiveRecord::Base
has_many :bids
has_many :advertisements, :through => :bids
has_many :offers, class_name: "Advertisement", foreign_key: :user_id
end
class Advertisement < ActiveRecord::Base
belongs_to :author, class_name:"User", foreign_key: :user_id
has_many :bids
has_many :users, :through => :bids
end
class Bid < ActiveRecord::Base
belongs_to :user
belongs_to :advertisement
end
So now, if you want to get Advertisement author you need to call
a = Advertisement.last
a.author
User Load (0.1ms) SELECT "users".* FROM "users" WHERE "users"."id" = 1 LIMIT 1
=> #<User id: 1, created_at: "2013-05-31 06:13:20", updated_at: "2013-05-31 06:13:20">
a.users
User Load (0.1ms) SELECT "users".* FROM "users" INNER JOIN "bids" ON "users"."id" = "bids"."user_id" WHERE "bids"."advertisement_id" = 2
=> [#<User id: 1, created_at: "2013-05-31 06:13:20", updated_at: "2013-05-31 06:13:20">, #<User id: 1, created_at: "2013-05-31 06:13:20", updated_at: "2013-05-31 06:13:20">]
See, it makes last select through joining bids, while first one just selecting from users table. Now it works like you expect it to work.
Anyway, answering your question:
Yes, you need to define new route like this:
resources :advertisements do
member do
post 'bid'
end
end
You need to create custom action in your AdvertisementsController which will do that:
def bid
#advertisement = Advertisement.find(params[:id])
current_user.bids << Bid.new(advertisement: #advertisement, value: params[:bid])
# you may also add some value column in bids table, thats up to you
redirect_to #advertisement
end
and form would be like this:
<%= form_tag(bid_advertisement_path(#advertisement), :method => "post",) do %>
<%= label_tag(:bid, "Make a bid:") %>
<%= text_field_tag(:bid) %>
<%= submit_tag("Submit") %>
<% end %>
If I am correct what you may want to have is a nested_form the gem for this can do exactly what you want. I say that you may have to use a nested form because by going by what you are saying a User has_many :bids which is correct. In order for the bids to accept the attributes from the user you will need to have accepts_nested_attributes_for :user on your Bids model. Tried to mock an example together for you
<%= form_for bid do |f| %>
<%= fields_for :user do |user_fields| %>
<%= user_fields.label :name %>
<%= user_fields.text_field :name %>
<% end %>
<%= f.label :product %>
<%= f.text_field :product %>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
Relevant links: 196 - Railscasts Nested Form
Related
I am creating simple blog level application. below are my models.
class User < ActiveRecord::Base
attr_accessible :name,:posts_count,:posts_attributes , :comments_attributes
has_many :posts
has_many :comments
accepts_nested_attributes_for :posts , :reject_if => proc{|post| post['name'].blank?} , :allow_destroy => true
end
class Post < ActiveRecord::Base
attr_accessible :name, :user_id ,:comments_attributes
belongs_to :user
has_many :comments
accepts_nested_attributes_for :comments
end
class Comment < ActiveRecord::Base
attr_accessible :content, :post_id, :user_id
belongs_to :user
belongs_to :post
end
I am trying to create user,post and comment in one form by using accepts_nested_attributes_for feature of rails. Below is my controller and view code.
Controller-----------
class UsersController < ApplicationController
def new
#user = User.new
#post = #user.posts.build
#post.comments.build
end
def create
#user = User.new(params[:user])
#user.save
end
end
Form----------
<%= form_for #user do |f| %>
<%= f.text_field :name %>
<%= f.fields_for :posts do |users_post| %>
<br>Post
<%= users_post.text_field :name %>
<%= users_post.fields_for :comments do |comment| %>
<%= comment.text_field :content %>
<% end %>
<% end %>
<%= f.submit %>
<% end %>
With the above code i am successfully able to create new user,post and comment but the problem is that i am not able to assign newly created user to newly created comment.when i checked the newly created comment into the database i got below result.I am getting user_id field value of "nil".
#<Comment id: 4, user_id: nil, post_id: 14, content: "c", created_at: "2014-05-30 09:51:53", updated_at: "2014-05-30 09:51:53">
So I just want to know how we can assign newly created comment to newly created user???
Thanks,
You will have to explicitly assign user_id for comments! You are nesting comments under posts, so comments would be having post_id assigned by default but though you are nesting comments under user form indirectly, there is no direct nesting of comments under user, so user_id remains blank in comments.
Try writing after create callback in Comment model to set user_id
In comment.rb
after_create{|comment|
comment.user_id = post.user_id
comment.save
}
Hope this helps :)
i have a form consists of the following models
Employee.rb
class Employee < ActiveRecord::Base
attr_accessible :employee_number, :joining_date, :first_name, :middle_name, :last_name,
:gender, :job_title, :employee_department_id, :qualification, :experience_detail,
:experience_year, :experience_month, :status_description, :date_of_birth, :marital_status,
:children_count, :father_name, :mother_name, :husband_name, :blood_group, :nationality_id,
:home_address_line1, :home_address_line2, :home_city, :home_state, :home_pin_code,
:office_address_line1, :office_address_line2, :office_city, :office_state, :office_pin_code,
:office_phone1, :office_phone2, :mobile_phone, :home_phone, :email, :fax, :user_id,
:reporting_manager_id, :employee_grade_id, :office_country_id,
:home_country_id, :employee_category, :employee_position_id
belongs_to :employee_department
has_many :counselor_supervisors
belongs_to :employee_position
def to_label
full_name = first_name + " " + last_name
end
end
EmployeeDepartment.rb
class EmployeeDepartment < ActiveRecord::Base
attr_accessible :code, :name
has_many :employees
has_many :employee_positions
has_many :counselor_supervisors
has_many :batch_leadership_supervisors
def to_label
name
end
end
CounselorSupervisor.rb
class CounselorSupervisor < ActiveRecord::Base
attr_accessible :employee_id, :employee_department_id, :employee_position_id
belongs_to :employee
belongs_to :employee_department
has_many :batch_counselor_supervisors
def to_label
employee.to_label
end
end
BatchCounselorSupervisor.rb
class BatchCounselorSupervisor < ActiveRecord::Base
attr_accessible :counselor_supervisor_id , :employee_department_id , :counselor_batch_id,
:batch_counselor_advisors_attributes
has_many :batch_counselor_advisors
belongs_to :counselor_supervisor
belongs_to :employee_department
belongs_to :counselor_batch
accepts_nested_attributes_for :batch_counselor_advisors
end
Employee_position.rb
class EmployeePosition < ActiveRecord::Base
attr_accessible :position_title, :employee_department_id
has_many :employees
belongs_to :employee_department
def to_label
position_title
end
end
batch_counselor_supervisors/new.html.erb (part of the form which related to my question)
<%= simple_form_for(#batch_counselor_supervisor) do |f| %>
<%= f.error_messages %>
<%= f.association :employee_department, as: :select %>
<%= f.input :counselor_supervisor_id , collection: EmployeeDepartment.all, as: :grouped_select, group_method: :counselor_supervisors %>
<% end %>
the dropdown list appears like this:
If I added an employee which belongs to the first department "Business Administration", the form will be displayed correctly like this:
Update: after adding label_method: :to_label, so my form became like this :
<%= simple_form_for(#batch_counselor_supervisor) do |f| %>
<%= f.error_messages %>
<%= f.association :employee_department, as: :select %>
<%= f.input :counselor_supervisor_id ,
collection: EmployeeDepartment.all, as: :grouped_select, group_method: :counselor_supervisors, label_method: :to_label %>
<% end %>
the employee name displayed correctly but still the department name not displayed correctly as the following image:
Is this SQLite3 issue ? and What can I do in order to solve this if it sqlite3 issue or not.
From what I see, you only have an issue with the labels not being displayed correctly. Could you try to explicitly set the method on your input:
label_method: :to_label
For more information have a look at https://github.com/plataformatec/simple_form and search for *label_method*
What are the actual relevant rows in your Employee table and your EmployeePosition table?
In your Employee table you happen to have these 2 columns;
employee_position_id
employee_position.
Since employee_position is also a table name, it's bad/reduntant model structure which might be confusing your include method of the query. It's possible that in your tables, the rows are fully filled out to complete the first query, but not for any of your other queries even though you think it is.
I have 3 models. Firstly I have a voter which has many votes. Votes is a join table to link the voter and the entry. But when I try to save the votes they are not saving. My models look like this:
class Vote < ActiveRecord::Base
belongs_to :entry
belongs_to :voter
attr_accessible :entry, :voter, :voter_id
class Voter < ActiveRecord::Base
attr_accessible :email_address, :verification_code, :verified, :votes_attributes, :votes
has_many :votes, :class_name => "Vote"
accepts_nested_attributes_for :votes
class Entry < ActiveRecord::Base
attr_accessible :caption, :email_address, :filename
end
I am then my form looks like this:
<%= f.fields_for :votes do |builder| %>
<fieldset>
<%= builder.label :votes, "Vote" %>
<%= collection_select(:votes, :entry_id, Entry.all, :id, :caption, :prompt => 'Please select an Entry') %>
</fieldset>
<% end %>
But the votes are not saving in the database. The response looks like this:
Parameters: {"utf8"=>"✓", "authenticity_token"=>"x5f85viIp/KHJKQF7DotaF3MhebARWcaLDKRbcZw/lM=", "voter"=>{"email_address"=>"sadasfd"}, "votes"=>{"entry_id"=>"3"}, "commit"=>"Create Voter"}
So whats going wrong?
Please try
class Voter < ActiveRecord::Base
attr_accessible :email_address, :verification_code, :verified, :votes
has_many :votes, :class_name => "Vote"
attr_accessible :votes_attributes,
accepts_nested_attributes_for :votes
Modify vote_params in VotesController
private
def vote_params
params.require(:vote).permit(:id, :email_address, :verification_code, :verified, votes_attributes: [:id, :name])
end
the problem I'm having is company_id is not been save to the details table
I know the company_id is there I check it using <%= debug(params[:id])%> on the form before adding all company details information but for some reason is saving everything else but the company_id
##user.rb
has_one :company
##company.rb
belongs_to :user
has_one :detail
##detail.rb
belongs_to :user
##details controller
def new
#detail = Detail.new
user_id = session[:user_id]
company_id = params[:id]
end
def create
#detail = Detail.new(params[:detail])
#detail.user_id = session[:user_id]
#detail.company_id = params[:id]
end
###settings.html.erb
### this is where i make sure that company_id gets pass with the url
link_to 'New Detail', {:controller => 'details', :action =>'new', :id => company.id }, :class => 'plus'
#####routes
resources :details
resources :companies
resources :users
resources :sessions
I know this may not look pretty or proper if you know a better way please let me know...thanks in advance.
I notice something immediately. You may need to fix your associations first. Assuming, a user has one company and a company has one detail.
##user.rb
has_one :company
##company.rb
belongs_to :user
has_one :detail
##detail.rb
belongs_to :user
Should be:
##user.rb
has_one :company
##company.rb
belongs_to :user
has_one :detail
##detail.rb
belongs_to :company
Although, depending on your domain requirements. I would normally have it as: User has_many Companies. And since details is 1:1 with company, I would include all the details inside company.
I didn't realize this until later but I need it pass values to from on the view to the from like so
<% #companies.each do |company| %>
<%= link_to 'New Detail', {:controller =>'details', :action => 'new', :company_id => company.id}, :class => 'plus' %>
<% end %>
and I need it to collect that value on the from...like so
<%= form_for(:detail, :url =>{:action => 'create', :company_id => #company.id}) do |f| %>
...(values)
<% end %>
Basically I have two models: User and Godfather. The godfather table has three columns:
user_id (FK --> User)
user_godfather_id (FK --> User)
description (text)
Inside each model class, I am adding the following associations:
class User < ActiveRecord::Base
has_many :godfathers # for user_id
has_many :other_godfathers, :foreign_key => "user_godfather_id", :class_name => "Godfather"
accepts_nested_attributes_for :godfathers
end
class Godfather < ActiveRecord::Base
belongs_to :user
belongs_to :user_godfather, :class_name => "User"
end
Now my question is about how to manage the edit form of this nested attribute relationships.
Here is how my form looks like at the moment (using the nested_form_for gem):
<%= nested_form_for #user do |f| %>
<%= f.fields_for :godfathers do |godfather_form| %>
# Here I have an ID text field but what I want instead is
# to provide a username for this godfather.
<%= godfather_form.label :user_godfather_id %>
<%= godfather_form.text_field :user_godfather_id %>
<%= godfather_form.label :description %>
<%= godfather_form.text_field :description %>
<%= godfather_form.link_to_remove "Remove this godfather" %>
<% end %>
<%= f.link_to_add "Add a godfather", :godfathers %> <br/><br/>
<%= f.submit "Update Godfathers" %>
So as I said in the comments, my goal is to be able to provide a username for the godfather instead of an id. That username is a column in the User table by the way.
Any idea about how I should go about it?
Thanks!
Just use different names for the relations
class User < ActiveRecord::Base
has_many :godfathers # for user_id
has_many :some_other_godfathers, :foreign_key => "user_godfather_id", :class_name => "Godfather"
accepts_nested_attributes_for :godfathers
end
Now you can use godfathers and some_other_godfathers.
Hope that helps :-)