Create new row after saving a record - ruby-on-rails

A user submits a url, this is put into into article.url through the scaffold create method. I can parse the url like so:
def parse_url
elements = #article.url.split("/")
if(elements[0] == "http:")
#home = elements[2] #elements[1] will be an empty string because of the // in the URL
else
#home = elements[0]
end
end
What I would prefer to do is to parse the url after the user saves it with the create method and then insert this value into a new row in the database in the article table.

I'd use something like the following:
class Article
attr_accessor :unparsed_url
before_validation_on_save :parse_url
private
def parse_url
return unless unparsed_url
elements = unparsed_url.split("/")
if(elements[0] == "http:")
self.home = elements[2]
else
self.home = elements[0]
end
end
end
You'd use unparsed_url in the Rails forms. Using a virtual attribute like this will work nicely with form validation.

Related

rails controller map unknown

In authors_controller.rb, I have this :
def show
a = Author.find(params[:id])
#author = a.map { |e| e.titlecase }
end
I get an error say that map is an undefined method for Author::0x007fec244142a0.
I also tried this :
def show
#author = Author.find(params[:id])
#author.each { |k, v| v.capitalize }
end
How can I apply the method titlecase to each value of Author.find ?
find(params[:id]) returns not array, not enumerator and not Relation class but just instance of your model. You can't use map or each so just apply titlecase to returned object.
def show
#author = Author.find(params[:id])
#author.name = #author.name.titlecase # if you have column 'name'
end
But better move titlecased name to model's method or just use #author.name.titlecase where it's needed.
You can use where and use map operator with it:
def show
#author = Author.where(id: params[:id])
It's ugly but it works. I'm sure there is a better way to do this stuff.
#author.attributes.map do |k,v|
v = #author.__send__(k).capitalize if #author.__send__(k).respond_to?(:capitalize)
end
#author.save
I must say however that I wouldn't recommend doing things this way. Better to capitalize each field in the model
From I understood. You want to capitalize all fields of record Author.find(params[:id]) right?
First, Author.find(params[:id]) will return a record, not array. That means you can't use each or map for it.
To capitalize all fields of a record. Could u try:
def show
author = Author.find(params[:id])
#author = author.attributes.values.map{|field| field.to_s.capitalize}
end
It will return an array of all field values.
UPDATE 1
For better
def show
author = Author.find(params[:id])
#author_info = author.attributes.values.map{|field| field.is_a?(String) ? field.capitalize : field}
end

POST Multiple Row to Database with fill out only one form on RAILS

I'm try to develop one rails application.
When I fill out the form, I'm getting this parameter.
"daysoff"=>{"offdate"=>"06/08/2015, 06/09/2015, 06/10/2015, 06/11/2015, 06/12/2015", "assign_id"=>"3", "user_id"=>"2"}
Here is my index controller,
def index
#people = User.all
#user = User.current
#daysoff = Daysoff.new
end
My table coloumns are offdate (date), user_id (int), :assign_id (int), so i want to post each date for one row and other column values must be same.
How should i write create controller ?
You could do something like
off_dates = params["daysoff"]["offdate"].try(:split,',')
off_dates.each do |off_date|
days_off = Daysoff.new
days_off.offdate = Date.strptime(off_date.strip, "%m/%d/%Y")
days_off.user_id = params["user_id"]
days_off.assign_id = params["assign_id"]
days_off.save!
end

better way to build association in controller

I need a link in a show method of a parent class for creating associated models, so I have the code:
link_to "incomplete", new_polymorphic_path(part_c.underscore, :survey_id => survey.id)
in a helper.
This links to a part, which has new code like this:
# GET /source_control_parts/new
def new
get_collections
if params[:survey_id]
#s = Survey.find(params[:survey_id])
if #s.blank?
#source_control_part = SourceControlPart.new
else
#source_control_part = #s.create_source_control_part
end
else
#source_control_part = SourceControlPart.new
end
end
I know this is not very DRY. How can I simplify this? Is there a RAILS way?
How about this:
def new
get_collections
get_source_control_part
end
private
def get_source_control_part
survey = params[:survey_id].blank? ? nil : Survey.find(params[:survey_id])
#source_control_part = survey ? survey.create_source_control_part : SourceControlPart.new
end

Remove current model instance from AR:Relation

I am creating an instance method on a model which returns instances of the same model. How can I ensure that the instance of the model that the method is being called upon is not part of the output?
My code is like this at the moment:
def other_versions(include_current = true)
if include_current
Coaster.where(order_ridden: order_ridden)
else
#coaster.other_version_count // Need this to exclude the current instance.
end
end
I'm not sure I understood, but would this help?
def other_versions(include_current = true)
query = Coaster.where(order_ridden: order_ridden)
query = query.where("id != ?", id) unless include_current
query
end

How to mimic asp.net get set in rails

I am trying to mimic asp.net get{} set{} in rails, here is what i tried in my controller:
def get_segment=(segment)
if params[:s] != nil
segment = params[:s]
else
segment = "personal"
end
end
Then i am trying to access it like this:
#something = get_segment
But it always returns as nil.
How can i do this?
Thanks
Why are you using get segment=(segment)?
look like what you are wanting to do is test params[:s], so the = is uncessary, as is the segment parameter.
def get_segment
if params[:s] != nil
params[:s]
else
"personal"
end
end
I think this would give you what you want.
If you just want to mimic get{} set{} in C#, the property Segment
private string _segment;
public string Segment {
get { return _segment; }
set { _segment = value; }
}
is written as followed in Ruby:
# get
def segment
#segment
end
# set
def segment=(value)
#segment = value
end
# if you don't have additional logic, you can just write
attr_accessor :segment
Then you can use some_instance.segment to retrieve the value and some_instance.segment = some_value to modify the value.
According to your code sample above, you want to fetch s parameter with a default value if it doesn't exist. You should define a getter, not in the setter form as you have provided.
def get_segment # or just "segment"
params[:s] || "personal"
end

Resources