Search code examples
javascriptruby-on-railsreactjsreact-reduxreact-rails

Can I call fields from associated model in react components?


Is there a way to get fields from associated model in react components in rails?

I have listing model that I am maping through in react component and getting all the fields within each record including the ID of the model that is associated to listing model that I am getting.

What I specifically want to achieve is to get another field through the associated ID that I have in listing model but, I am not getting it just like we do in rails, for example

listing.modelNameThatIsAssociated.fieldName

How to achieve this?

here a snippet of my code

controller

def all
 begin
   @listings = Listing.all
 rescue => e
   @listings = []
 end
end

def filter
 @listings = Listing.where(nil)

 filtering_params(params).each do |key, value|
   @listings = @listings.public_send(key, value) if value.present?
 end 
 render json: { listings: @listings }, status: 200
end

private
def filtering_params(params)
  params[:filters].slice(:bedrooms, :bathrooms, :price, :parking)
end

all.html.erb

<%= react_component('ListingsPage', listings: @listings) %>

And here My react component(listings.js.jsx)

class ListingsList extends React.Component {
    constructor(props) {
      super(props);
}

render() {
  const { listings } = this.props;

    return (
      <div className='ListingList_container'>
        <table>
          <thead>
           <tr>
            <td>#</td>
            <td>Name</td>
            <td>Address</td>
            <td>Lat</td>
            <td>Lng</td>
            <td>Bedrooms</td>
            <td>Bathrooms</td>
            <td>Price</td>
            <td>Parking</td>
            <td>Building ID</td>
          </tr>
        </thead>
          <tbody>
          {
            listings.map((listing, index) => (
              <tr key={listing.id}>
                <td>{index + 1}</td>
                <td>{listing.name}</td>
                <td>{listing.address}</td>
                <td>{listing.lat}</td>
                <td>{listing.lng}</td>
                <td>{listing.bedrooms}</td>
                <td>{listing.bathrooms}</td>
                <td>{this.formatNumber(listing.price)}</td>
                <td>{listing.parking ? 'Available' : 'None'}</td>

                // below I want to get building name just like we do in rails
                // through association 'listing.building.name' but, that
                // doesn't work
                <td>{listing.building_id}</td> // this works, I am getting building ID
               <td>{listing.building.name}</td> // this doesn't work
              </tr>
            ))
          }
        </tbody>
      </table>
    </div>
  );
 }
}

I appreciate every single view and help thanks in advance. Please let me know if my question is not clear.


Solution

  • You'll have to load the associations first, then use the include option in as_json to add them to the JSON output

    For example, if your Listing model has_many :offers and has_many :views, then you would write this:

    # In the controller
    @listings = Listing.preload(:offers, :views)
    
    # In your view
    <%= react_component(
      'ListingsPage', 
      listings: @listings.as_json(include: [:offers, :views])
    ) %>