I want for every users to have only one row of data in a table named business. He can edit it for the second time.
Also i want to submit each column value separately using form_for but when i do like this when submitting the form for the second time for a different column entry, it goes to the second row making the previous row empty.
How can i achieve this?
Here is my code...
<%= form_for #new_business do |f| %>
<%= f.text_area :first_problem %>
<%= f.submit %>
<% end %>
A screenshot of the data table
Table data screenshot
Any help is appreciated as i am new to rails. Thanks.
One user can only have one business, you need to set relationship between them
In user.rb model
has_one :business
In business.rb model
belongs_to :user
For your second problem, i think you are not passing row id for which you want to update columns, so everytime it is creating a new entry for that column
It looks like your code snippet is from your new template (i.e. "app/views/businesses/new.html.erb"). This should only be used when you want a new object created. Your controller probably says something like
def new
#new_business = Business.new
end
When the form is submitted, the :create action in your controller gets called, which should create a new record in the database.
When you want to edit that object, you use an edit action in your controller that corresponds to an edit.html.erb view. Something like this in the controller:
def edit
#business = Business.find(params[:id])
end
with a similar form to the one you listed above in the view. When that form is submitted, it should route to an :update action in your controller, that updates the existing record in the database.
The tricky part about what you are trying to accomplish is limiting each user to only being able to create one record in the database. There are many ways to go about doing this, but the general idea would be to restrict the user's access to the new and create actions in the controller once they have already created a record. You can do that by using before_action (if using Rails 4.0 or greater) or before_filter (if using Rails < 4.0) to call a method that checks if a user has already created a record.
Related
Let's say I have a Customer and a Brand class (where a customer has many brands and a brand belongs to a customer). When the user is on the show page for a specific customer, he/she has the option to click a button to add a new brand (that button redirects to the form to create a new brand, which contains a field where the user should indicate which customer that brand belongs to). But when the user gets to that form, he/she should not have to manually indicate which customer that brand belongs to, but rather that information should be entered automatically based on the customer_id of the customer whose show page the user was just looking at. If no show page was being looked at, the field for the parent customer_id should be empty (as it is by default) and the user should enter it manually.
Is there a way to implement this in Rails? If so, how?
Your question is a bit hard to understand, but let's go.
First, you have to create a link to a new brand, something like:
<%= link_to 'New brand for #{#customer.name}", new_brand_path(customer_id: #customer.id) %>
In this way you are passing the customer_id as a param.
In the brand controller on the new action you will do
def new
#customer = Customer.find_by_id(params[:customer_id])
#brand = #customer ? Brand.new(customer_id: #customer.id) : Brand.new
end
You see that I made an example to make it clear what to do. There are better ways of doing that, but I guess this will guide you through what you want.
On the link from the show page, you could have something like this
<%= link_to 'New Brand', new_brand_path(customer_id: params[:id]) %>
Then in the controller, you could have some code that checks to see if the customer_id is present in the params hash in the new action:
#brand.customer = Customer.find(params[:customer_id]) if params[:customer_id]
Now, when the form is rendered, assuming using form_for #brand, the customer field will be set.
If they are linking from another page (other than show), then just don't pass in the customer_id: params[:id] in the link_to method call. It will bypass the if statement in the controller and the customer will be blank.
#new_brand = #customer.brands.new
It populates cusomer_id in #new_brand with correct value
I am totally new to Ruby on Rails, I was following some tutorials and developed a small CRUD application. In a form I have a drop down which was previously filled with hard coded values but now I have populated it with the values retrieved from database which works fine, but the trouble is I intend to get the selected value of the dropdown but instead of that I end up getting the id of that value, I know I am doing something logically wrong, I have did some research but was unable to come across a solution that fulfilled my requirement.
Here is my controller action,
def new
#list=CategoryType.all
end
Here is the dropdown within the form:
<%= f.label :maincategory %>
<% options = options_from_collection_for_select(#list, 'id','maincategory') %>
<%= f.select :maincategory, options %>
And this is the action getting back the parameters from the form in the controller:
private
def category_params
params.require(:category).permit(:name, :maincategory)
end
And this action saves it in the database:
def create
#category= Category.new(category_params)
if #category.save
redirect_to #category
else
render 'new'
end
end
Instead of maincategory id is being saved in the database, i am totally new to ROR, would really appreciate the help. Thanks in advance.
Why would you save the maincategory as a string ?
I suppose in your Category model, you should have a belongs_to :category_type.
I think it's better to save the CategoryType id of your maincategory object.
This way, you have the correct relation between your category and its type. Therefore, you could have the CategoryType of your category with this command : #category.category_type.name, if you want to retrieve the name of your record, as your data relation would be correct.
Let me know if I misunderstood something !
Model:
Users have expenses. Expense has a status.
View:
As users add their expenses, they are shown in a list. Each expense row has a form button on the end, which is used to submit the expense (changing the status of the expense). This allows users to add expenses they have not completely filled out, and submit them when they are ready. There is no parent form on this page, just the form buttons which submit the expense to a method which changes the status, and then reloads the page.
Currently it works great, but users have asked to be able to "submit all" the expenses that are showing on the view with a single button.
Question:
What is the proper way to handle this in rails? Should I find a way to gather the array of expense id's and then submit a separate form? Is there a way to ask for a set of records present in a view with a certain status?
Thanks!
Another option, if I'm thinking about this right (big if), would be to wrap your page in a User form. Then you could have something like...
<%= form_for(#user) do |f| %>
<% #user.expenses.each do |expense| %>
<% f.fields_for expense do |e| %>
<!-- expense form -->
<% end %>
<% end >
<% end %>
This is something you could submit as a whole. I'm having trouble picturing what a single expense addition might look like, but hopefully this gets you a little further down the road.
Edit: in addition to having this User form on the page, you could have an "extra" Expense form to create an expense. When you submit a new expense, that expense appears in the list under the user form, where it can be edited or submitted, either as part of a group or individually (as part of a "group" of 1).
custom controller action:
def update_all_expense_statuses
expenses = current_user.expenses
ExpenseUpdater.new(expenses).update_expense
redirect_to :back
end
expense updater class:
class ExpenseUpdater
def initialize(expenses)
#expenses = expenses
end
def update_expense
#expenses.each do |expense|
expense.update_attributes(status: 'paid')
expense.save
end
end
end
This is just an example of one way to update all the user's expenses with a custom controller action. Just call the controller method from a link_to:
<%= link_to "Update all expenses", update_all_expense_statuses_path %>
Remember to add it to your routes. Hope this helps.
The first thing you should do is change the forms to submit remotely, ie make an ajax request. Then you're not reloading the whole page. Check out Rails' various "remote" form helpers, eg "remote_form_for".
Then, write a javascript function to submit all the forms for inputs that have changed since the page loaded. You'd probably want to add a "changed" (or similar) class to the parent form in an onchange event in each input, to facilitate this. I think this is the best way to handle the "status" thing you're asking about. Make a "Submit all" button which calls this function.
Use a form/service object http://blog.codeclimate.com/blog/2012/10/17/7-ways-to-decompose-fat-activerecord-models/ to encapsulate expense report
campaign.rb
class Campaign < ActiveRecord::Base
has_many :items
accepts_nested_attributes_for :item
end
item.rb
class Item < ActiveRecord::Base
belongs_to :campaign
end
Campaign has 2 attributes: title and description
Item has 1 attirubte: name
I'll try explain myself by words, I want to create a nested form where they user insert the campaign's name and description but he can insert more than just 1 item, he can insert a list of items (in particular there will be a "+" button that when clicked a new item row will appear and the user can insert items).
At the end all is send all together clicking just one submit button.
How can I reach my goal with rails?
I answered a question just yesterday. Here's the link: Rails accepts_nested_attributes_for with f.fields_for and AJAX
I'll write out how it works & provide some resources to help give you some more ideas:
How It Works
Loading associative fields into a form is done by using f.fields_for
You'll do it like this:
#app/views/campaigns/new.html.erb
<%= form_for #campaign do |f| %>
<%= f.fields_for :items do |a| %>
<%= a.text_field :information %>
<% end %>
<% end %>
In order to get this to work, you have to build the associated ActiveRecord objects in the backend before you render the view, like this:
#app/controllers/campaigns_controller.rb
def new
#campaign = Campaign.new
#campaign.items.build
end
Adding Extra Fields Via Ajax
Adding extra fields with Ajax requires engineering a new solution to the issue
The way you do this is to take the f.fields_for text & put it into a partial. This partial can be called from the original view, as well as another view (which we can render through Ajax)
The Ajax part works by basically taking a request from your form (the ajax request), and then using another action in your controller to build a new ActiveRecord object & render another partial that will contain another form. This partial will then call the original f.fields_for partial, allowing you to render another field
Your Ajax can then extract the new field & append it to your page. The way you get around the id issue (keeping the IDs sequential & unique) is to employ the child_index method, and use Time.now.to_i to generate a timestamp
If you read my answer referenced at the top of this answer, all of this will make sense :)
Some great resources for this:
RailsCasts Nested Forms
Adding Fields With Ajax
A nice gem along with tutorial is available from ryanbates who is the author of railscasts.com site.You can use this and have a look at tutorial here
And also if you want to try manually use the fields_for while writing in the form like here and manage some jquery code for add or remove.
I would like to know which way is the best to resolve my question :
I have a form in order to select people via a select field. If the name is missing in the select field, a text field is available to add directly the person's name.
- The form in new.html.erb is the format of the new action of the Team controller.
- The list of the people is extracted from the People model.
def new
#team = Team.new
#people = People.all
end
I created an attribute in the Team model to store the new_person text field :
class Team < ActiveRecord::Base
attr_accessor :new_person
...
end
Finally, here's an extract of my view :
<%= f.select :person_id, #people.map { |p| [p.name, p.id] } %>
<%= f.text_field :new_person %>
Obviously, I would like to save the new person in the table Person before saving the data from the form. As usual, the id are saved instead of the names
At this point, I've got two issues :
1/ The params array has the key new_person what doesn't have the table. So it is not possible to use the Team.new(params[:team]) method. Does exist an easy solution to avoid this problem ?
2/ As I need the person_id, how can I get it when the name comes from the new_person field? In using the before_filter method ?
Thanks a lot,
Camille.
1) You should consider using fields_for in your view within your form_for block. This will allow you to specify that the fields within the fields_for block are attributes of a different model, will generate the appropriately named input fields, and allow you to use params[:team] in your controller. See the FormHelper documentation for more on this.
2) While you could do something in your controller to first check for a value in the new_person field, create the record, update the contents of params[:team] with the value of the newly created person and create the team, this feels a bit like a hack to me. Another possible solution which may be less fragile would be to use some JavaScript on the page that would render some kind of modal dialog for the user to create the new person, submit the new person to the person#create controller method, then refresh your drop down. It would probably not be terribly difficult to do this using a jQuery UI modal form (very good example at that link to do what you need) with Rails remote form and unobtrusive JavaScript.
This is probably a more difficult solution to your second question than you are hoping for, but probably more useful in the long run.