How to mimic asp.net get set in rails - ruby-on-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

Related

Check request parameter

I want to check request header parameters. If an attribute is missing , I don't accept the request.
Current implementation is here:
class SampleController < ApplicationController
before_action :render_message, unless: :check_header
// GET method
def index
....
end
def check_header
return request.headers["key1"] && request.headers["key2"] && request.headers["key3"]
end
def render_message
render json: { message: "missing the custom attribute in the header" }, status:400
end
How can I beautify this code?
I would probably rewrite the method to something like this:
def check_header
required_headers = %w[key2 key2 key3]
required_headers.all? { |key| request.headers[key] }
end
Note that the above version has the same behavior then your example. If you really need to check that the values are present (an empty string is still true-ish) then you will need to check present? too.
def check_header
required_headers = %w[key2 key2 key3]
required_headers.all? { |key| request.headers[key].present? }
end
And I would think about using a constant instead of the local variable required_headers.

Setting multiple model attributes at once via loop

Im using virtual attributes to concat and form a address before i save the user. So when they click edit user i would like to populate the fields in the form again. Every time i try to assign them they come back nil?
This is what i call from devise registrations controller before_action edit:
def test
resource.populate_address_attributes
end
and here is the method im trying to work with:
def populate_address_attributes
if address == nil || address == ""
return false
else
attributes = address.split(",")
[self.number, self.street_name, self.area, self.postcode, self.state].each { |x| x = attributes.delete_at[0]}
end
end
all i'm getting is this:
=> [nil, nil, nil, nil, nil]
maybe i'm trying to make it to complicated?
When you are passing [self.number, self.street_name] etc you are passing the value of those attributes (which are nil and hence immutable).
Try this
def populate_address_attributes
if address == nil || address == ""
return false
else
attributes = address.split(",")
[:number, :street_name, :area, :postcode, :state].each_with_index do |field, index|
self.public_send("#{field}=", attributes[index])
end
end
end

Ruby: adding multiple rows to a hash key

I've got a class that looks like this:
class VariableStack
def initialize(document)
#document = document
end
def to_array
#document.template.stacks.each { |stack| stack_hash stack }
end
private
def stack_hash(stack)
stack_hash = {}
stack_hash['stack_name'] = stack.name
stack_hash['boxes'] = [stack.boxes.each { |box| box_hash box }]
stack_hash
end
def box_hash(box)
box_hash = {}
content = []
box.template_variables.indexed.each { |var| content << content_array(var) }
content.delete_if(&:blank?)
box_hash.store('content', content.join("\n"))
return if box_hash['content'].empty?
box_hash
end
def content_array(var)
v = #document.template_variables.where(master_id: var.id).first
return unless v
if v.text.present?
v.format_text
elsif v.photo_id.present?
v.image.uploaded_image.url
end
end
end
The document I'm testing with has two template_variables so the desired result should be a nested hash like so:
Instead I'm getting this result:
=> [#<Stack id: 1, name: "User information">]
i.e., I'm not getting the boxes key nor it's nested content. Why isn't my method looping through the box_hash and content fields?
That's because the to_array method uses each method, which returns the object it's been called on (in this case #document.template.stacks)
Change it to the map and you may get the desired result:
def to_array
#document.template.stacks.map { |stack| stack_hash stack }
end

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

Create new row after saving a record

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.

Resources